A、表达式求值
题目简述:给你一个表达式,包括+、*以及()和Smax。让你求最后值。
一个字符串处理题,可以模拟栈来操作。每当读进一个(,则记录下位置及(个数,每读进一个)时,可以先求出这个括号内的值,(的位置用数组记录下来了,最后出现的就是。 并且为了同Smax的()区别开,可以定义不同值区分。处理完括号之后剩下+、*。扫一遍就好了。
#include<iostream>
#include<cstring>
using namespace std;
int Smax(int n, int m)
{
int i, j;
i = j = 0;
while(n!=0)
{
i = i + n%10;
n/=10;
}
while(m!=0)
{
j = j+m%10;
m/=10;
}
return i>j?i:j;
}
int oo(int i, int j, int b[]) //判断i-j内的结果,这里面只有加号和乘
{
int k = 0, x, y;
x = i;
y = j;
for(i; i < j; i++)
{
if(b[i+1] == -5)
{
b[i+2] = b[i]*b[i+2];
b[i] = -1;
i++;
}
}
for(i = x; i <= j; i++)
{
if(b[i] >= 0)
k+=b[i];
}
return k;
}
int main()
{
char a[1001];
int n, i, j, k, l, m, b[1001], t, c[1001][2],x,y,z;//用-1代表Smax,-2代表普通的(,-3代表),-5代表*,-9代表,
cin >> t;
while(t--)
{
k = 0;
cin >> a;
n = strlen(a);
m = 0;
for(i = 0; i < n; i++)
{
if(a[i] == '(')
{
m++;
b[m] = -2;
k++;
c[k][0] = -2;
c[k][1] = m;
}
else if(a[i] == ')')
{
m++;
b[m] = -3;
if(c[k][0] == -2)
{
j = c[k][1];
b[j] = oo(j+1, m-1, b);
m = j;
k--;
}
else
{
j = c[k][1];
for(z = j; z <= m; z++)
if(b[z] == -9)
break;
x = oo(j+1, z-1, b);
y = oo(z+1, m-1, b);
b[j] = Smax(x, y);
m = j;
k--;
}
}
else if(a[i] == '+')
{
m++;
b[m] = -4;
}
else if(a[i] == '*')
{
m++;
b[m] = -5;
}
else if(a[i] == 'S')
{
m++;
for(i; i < n; i++)
if(a[i]=='(')
break;
k++;
c[k][0] = -1;
c[k][1] = m;
b[m] = -1;
}
else if(a[i] == ',')
{
m++;
b[m] = -9;
}
else
{
m++;
l = 0;
for(i ; i < n; i++)
if(a[i]<'0' || a[i]>'9')
break;
else
l = l*10+a[i]-'0';
b[m] = l;
i--;
}
}
cout << oo(1, m, b) << endl;
}
}
B、宣传墙
B题可以通过找公式来做出来。已知宽是4。我们可以推出大致有四种
一、第一行两个横着放,余下的就是 f(n-1)种情况。
二、前两行全是竖着放,余下就是f(n-2)种情况。
三、两边放竖着,中间放横着,那么中间空的两个放一个横的就有f(n-2)种情况,也可以接着放竖着,再放横着。就有f(n-4)情况,总共f(n-2)+f(n-4)…
四,一边放横着,一边放竖着。于是可以选择空的地方放一个横的,就有f(n-2)种情况,也可以放两个竖的再放横的,有f(n-3)种情况。总共f(n-2)+f(n-3)…注意求出来结果*2.因为对称是一样的。
C
省赛简单题,找一条1到n的路径乘积最小。直接优先队列BFS就好了。不要直接数组。。。犹记得比赛被队友骗了直接10000*10000数组跑。233333
D
生于忧患_死于安乐
首先感谢下这位博主,这题做法也是源于这里。
http://my.csdn.net/WR_technology
题目链接导弹发射
题意一定要读懂!!! 前进就是x,y严格增加。点重合也只算一个。
还有!!! 你的两个点之间斜率也要在雷达两条线之间。
首先把雷达外的点移除去。
之后建立以两条雷达线为X,Y轴。
然后按照x或y进行从小到大排序,相同则对另一个值从大到小排。
然后就是nlogn的最长严格上升子序列。(用一个a[i]表示长度为i时最小值为多少)
E
也是一个简单题。。求最路径长度。注意double存就好了。比赛没过,代码int改double直接过233333. 最短路,bfs都可以做。
F
省赛签到题,直接枚举所有可能情况就好了。
G
简述:让你建立N个二叉搜索树,看有多少种形状不同的。
于是可以简单模拟下建立过程。每个数的位置用a[i][j]记录。 首先与第一个数比较,大于等于找a[i][j]*2+1, 小于则找有没有a[i][j]*2,找到了改变j值再次寻找。最后找不到就可以确定这个数的位置。
模拟建立代码如下
cin >> n >> k;
for(i = 1; i <= n; i++)
{
cin >> b[1];
a[i][1] = 1;
for(j = 2; j <= k; j++)
{
cin >> b[j];
y = 1;
x = b[1];
while(1)
{
if(b[j] >= x)
{
for(l = 2; l < j; l++)
if(a[i][l] == y*2+1)
{
x = b[l];
y = y*2+1;
break;
}
}
else
{
for(l = 2; l < j; l++)
if(a[i][l] == y*2)
{
x = b[l];
y = y*2;
break;
}
}
if(l == j)
{
if(b[j] >= x)
a[i][j] = y*2+1;
else
a[i][j] = y*2;
break;
}
}
}
}
H
除了暴力并不会DP。。。。。。
第一篇博客。。格式、内容等方面确实不太合理,有什么不满的地方请见谅。以后会更加努力的。