1. 程式人生 > >ZCMU 1795: wjw的hard problem(dfs+思維)

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;
}