xdoj五星题172 构造表达式
标题
构造表达式
类别
综合
时间限制
1S
内存限制
100Kb
问题描述
给定一个表示序列长度的整数n(3<=n<=9)。在序列1 2 3…n中插入‘+’,‘-’,‘ ’构造表达式,插入‘ ’表示前后两个数字构成一个整数,例如1 2 -3 -4 -5=0。
输出构造的所有表达式中,结果为0的表达式的数量,例如n=3时,只有表达式1+2-3=0,输出结果为1。
输入说明
输入数据为一个整数n(n<10),表示序列长度,同时表示输入序列为“1 2 3…n”。
输出说明
对于每一组数据,输出一个整数,表示构造的表达式中结果为0的表达式数量。
输入样例
3
输出样例
1
题目思路:
想用递归的方法来整这个题。
快捷的数学方法我是想不到了(QAQ)
目前只想出两种方法:
**1.**将n个数之间的n-1个空格转换成三进制,用0代表+,用1代表-,用2代表“ ”,这样相当于是给了输入然后用函数去算这个表达式,省去了递归的过程,只需要遍历即可。
**2.**我自己用的递归。从第一个数开始压栈,之后判断这个数之后的符号,如果是加减直接去搜索后一位数,把这个数放在其后的位置就可以了。
如果是空格比较麻烦,这时候要用一个head和tail,分别表示他的首尾(用来处理连续的空格),然后每放进一个去,就让前面的×10,100,1000……(看具体前面有多少个空格,这个长度可以用tail-head来计算)。
在写这部分代码的时候,有几点我修改的比较多:
1.在什么时候改变point和tail,让他们指向下一个点进行修改。
2.在for循环的开始还是结尾去判断是否已经搜索到底(最后写在开头);
3.关于head的位置,如果不写那个while循环,他会每次都少一块,所以通过while循环让head移动到第一个后面是空格的位置。
4.在调试的时候,会出现多余几次的加和(其实对结果没啥影响,就是多运行了几次),所以我就在最后加了一个a[n]!=0,其实也没啥用。
5.对tail、point和head的移动处理,我也是边试边写的,过程的话还是自己画画草图吧。
其实题也不算特别特别难(往往做完之后都这么觉得),还是对递归回去各个数的改变太不熟悉了……一定多练题!!(大概)
ps:xdoj上反正提交是不给评判,管他的呢,反正自己有收获,oj算个xxxxx……
ps2:第二天试了一下都能AC,两个代码都可以
代码是递归思路写的,先附上自己的代(乱)码:
#include<stdio.h>
int a[20]={0};
int head=1,tail=1;
int point=1;
int n;
int ans=0;
int main()
{
void dfs(int);
scanf("%d",&n);
a[1]=1;
dfs(1);
printf("%d",ans);
}
void dfs(int point)
{
int i,j;
for(i=1;i<=3;i++)
{
if(point==n)
break;
if(i==1)//此处为+
{
point++;
a[point]=point;
tail=point;
head=tail;
dfs(point);//在这里递归
a[point]=0;//这一部分是用来进行改变的
point--;
tail--;
if(head>tail)
head=tail;
continue;
}
if(i==2)//这里是- ,和+基本一样
{
point++;
a[point]=-point;
tail=point;
head=tail;
dfs(point);
a[point]=0;
point--;
tail--;
if(head>tail)
head=tail;
continue;
}
if(i==3)//这里是空格,最难写的地方
{
point++;
tail=point;
int lenth=1;
while(a[head-1]>=10||a[head-1]<=-10)//这是用来找第一个空格位置的,把head指过去
head--;
for(j=tail;j>=head;j--)//分正负进行讨论
{
if(a[head]<0)
a[j]=-j*lenth;
if(a[head]>0)
a[j]=j*lenth;
lenth*=10;
}
dfs(point);
a[point]=0;
point--;
tail--;
if(head>tail)//这个处理突发奇想,防止head在tail后面
head=tail;
continue;
}
}
int sum=0;
for(j=1;j<=n;j++)
sum+=a[j];
if(sum==0&&a[n]!=0)//其实第二个没啥用,是自己代码烂了,打个补丁
ans++;
}
代码有不好或者绕弯路的地方太正常了,我还只是个刚学c语言的大一弱鸡,求放过~
另一种非递归转三进制的方法有室友写了,我就不再整活了,放一下:
亿点感慨:
从下午七点写到晚上1点,虽然不难吧但是对于不熟练的我真的是疯狂折磨。在调试中度过一晚上,不过还好,至少学到东西了吧(而且有人陪着写也没那么累)。而且,竟然有人看我博客?本来是写了给自己看的,结果不知道哪位大聪明找到这里来了(HAHAHA~)
ps3:这算不算dfs?我也不是很清楚😂,叫什么的吧反正是递归就完事了(手动狗头)如果有同学没看懂或者有什么意见欢迎私信我鸭~