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其实代码挺短的,对别人来讲好像也挺简单的,但是听别人给我讲的时候,还是觉得接收了好多信息量,搞了很久。还是这么菜(╥╯^╰╥)
- 字符串只有20位,所以直接搜应该是不会超时的。
- 枚举等号的位置,可能的位置有0~len-1的后一个位置。把这一段区间分成两部分,等号左边就是[0,i],右边则为[i+1,len-1];这样,分别算两端的和sum1、sum2;
- dfs函数参数:deep--当前遍历到的字符的位置;stop--等号的位置;sum1:左端和;sum2:右端和;pre:每次要加进去的数。
- 注意数据范围,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;
}