A 表达式求值
表达式求值:可以用递归求解,也可以用栈模拟,考过多次。
类似题目:NYOJ305,NYOJ35
用栈模拟做法:
#include <stdio.h>
#include <string.h>
#include <stack>
using namespace std;
stack<int> dsta;//数据栈
stack<char> osta;//字符栈
char s[1005];
int main()
{
int T,i,j;
scanf("%d",&T);
while(T--)
{
scanf("\n%s",&s[1]);
int len=strlen(&s[1]);
s[0]='('; s[++len]=')';//在给定的表达式两端添加上一对括号
for(i=0;i<=len;i++)
{
if(s[i]=='(')
osta.push(s[i]);
else if(s[i]=='S')
{
osta.push('(');//压入一个左括弧
i+=3;
}
else if(s[i]>='0' && s[i]<='9')
{
int v=0;
while(s[i]>='0' && s[i]<='9')
v=v*10+(s[i++]-'0');
i--;
dsta.push(v);
}
else if(s[i]=='+')
{
while(osta.top()!='(' && osta.top()!=',')
{
int a=dsta.top(); dsta.pop();
int b=dsta.top(); dsta.pop();
int c;
switch(osta.top())
{
case '+':c=b+a;break;
case '*':c=b*a;break;
}
dsta.push(c);
osta.pop();
}
osta.push(s[i]);
}
else if(s[i]=='*')
{
if(osta.top()=='*')
{
int a=dsta.top(); dsta.pop();
int b=dsta.top(); dsta.pop();
dsta.push(b*a);
osta.pop();
}
osta.push(s[i]);
}
else if(s[i]==')' || s[i]==',')//遇到逗号及时求值
{ //当遇到 ','时,就把Smax的前半部分表达式的值求出来
//运算符号 都在这里计算 + - * / smax自定义
while(osta.top()!='(')
{
int a=dsta.top(); dsta.pop();
int b=dsta.top(); dsta.pop();
int c,suma=0,sumb=0;
switch(osta.top())
{
case '+':c=b+a;break;
case '*':c=b*a;break;
case ',':{
//逐位分割求和
while(b!=0)
{
sumb+=b%10; b/=10;
}
while(a!=0)
{
suma+=a%10; a/=10;
}
c=max(suma,sumb);
break;
}
}
dsta.push(c);
osta.pop();
}
osta.pop();
if(s[i]==',')//求完值之后,把逗号压入栈内,以便后半部分Smax表达式的求值
osta.push(s[i]);
}
}
printf("%d\n",dsta.top());
dsta.pop();
}
return 0;
}
B 宣传墙
状压dp 推状态转移
或者用矩阵快速幂优化
网上代码看不懂。。。
C 信道安全
单源点的最短路修改版,用dijkstra做,初始化dist数组和松弛改一下就可以了。
D 导弹发射
LIS的二分写法,数据量1e5 O(N^2)的会超时。
另外题目中说的 导弹一直在前进,不能以原来的X/Y轴作为坐标轴了,需要坐标变换以两条射线为坐标轴
E 机器设备
我用bfs搜索做的,从原点(0,0)开始搜,每次将与当前点相切的圆心齿轮加入到队列,这里的相切意思是:两个圆心距离等于两个圆半径和
F Decimal integer conversion
题意:给一个十进制数 的二进制数 和一个 三进制数,其中各有一位是错的,求正确的十进制数
枚举一下就可以了,二进制和三进制 转成10进制后出现相同的数就是答案
G Prototypes analyze
一个二叉搜索树,问形状有多少个。
明天看题解,学会建树吧......