xdoj五星题172 构造表达式(递归思路)

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语言的大一弱鸡,求放过~

另一种非递归转三进制的方法有室友写了,我就不再整活了,放一下:

xdoj-172 构造表达式 ——snow_cx

亿点感慨:
从下午七点写到晚上1点,虽然不难吧但是对于不熟练的我真的是疯狂折磨。在调试中度过一晚上,不过还好,至少学到东西了吧(而且有人陪着写也没那么累)。而且,竟然有人看我博客?本来是写了给自己看的,结果不知道哪位大聪明找到这里来了(HAHAHA~)

ps3:这算不算dfs?我也不是很清楚😂,叫什么的吧反正是递归就完事了(手动狗头)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章