ZCMU 1795: wjw的hard problem(dfs+思维)

ZCMU 1795: wjw的hard problem

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 69  Solved: 21
[Submit][Status][Web Board]

Description

ly最近给wjw出了一个很难很难的题目,ly给了wjw一串数字,wjw可以在这串数字中间插入一个“=”使得这串数字变成一个等式,然后他还可以插入不限个数个"+",比如“945”可以分成9=4+5,“3434”可以分成“34=34”或者“3+4=3+4”两个等式,因为数字长度一增加,wjw就不会算了,现在他请你帮他算一下每个数字串有能分成多少种等式?

Input

每组测试数据有多组,每组一个数字串,长度保证(2<=len<=20),输入以0结尾

Output

对每组数据输出,每组一行,包含一个整数,表示答案

Sample Input

1212

1235

0

Sample Output

2

0

【分析】emmm其实代码挺短的,对别人来讲好像也挺简单的,但是听别人给我讲的时候,还是觉得接收了好多信息量,搞了很久。还是这么菜(╥╯^╰╥)

  1. 字符串只有20位,所以直接搜应该是不会超时的。
  2. 枚举等号的位置,可能的位置有0~len-1的后一个位置。把这一段区间分成两部分,等号左边就是[0,i],右边则为[i+1,len-1];这样,分别算两端的和sum1、sum2;
  3. dfs函数参数:deep--当前遍历到的字符的位置;stop--等号的位置;sum1:左端和;sum2:右端和;pre:每次要加进去的数。
  4. 注意数据范围,sum1和sum2及pre都是有可能超过int范围的,所以用long long;

【代码】

#include<bits/stdc++.h>
using namespace std;
int len,ans;
char s[25];
#define ll long long
void dfs(int deep,int stop,ll sum1,ll sum2,ll pre)
{
	if(deep>=len)//到达最后一位
	{
		if(sum1==sum2)
			ans++;
		return;
	}
	pre=pre*10+s[deep]-48;//注意要在这里计算pre,不能放到if里
	if(deep==stop)//等号的位置
		dfs(deep+1,stop,sum1+pre,0,0);//注意pre清零
	else
	{
		if(deep!=len-1)dfs(deep+1,stop,sum1,sum2,pre);//只有在不是最后一位时,才执行此句;
		if(deep<stop)dfs(deep+1,stop,sum1+pre,0,0);
		else dfs(deep+1,stop,sum1,sum2+pre,0);
	}
}
int main()
{
	while(~scanf("%s",s)&&s[0]!='0')
	{
		len=strlen(s);ans=0;
		for(int i=0;i<len-1;i++)
			dfs(0,i,0,0,0);
		printf("%d\n",ans);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38735931/article/details/82952450