HDU:4403 A very hard Aoshu problem
阿新 • • 發佈:2019-02-17
這要要用回溯法來做。好久沒做回溯的題了,幾乎忘光了~
但是我開始看到這個題的時候居然一點思路都沒有。回想以前做過的回溯題,八皇后,數學表示式,全排列都有一個特點,都是試圖枚舉出全部情況,只不過有些不合要求的情況被直接否了。這種列舉是層次性的,可以說是無限個迴圈,不是幾個迴圈可以寫出來的。 這道題,放的加號沒有限制,等號只能放一個。
先寫一個迴圈列舉等號的位置,然後就進入遞迴可以列舉加號的位置。
好好領會吧~
這裡有一些注意的地方。比如說判斷等式左右是否相等的方法是當進入等號右邊以後原和取其相反數,最後看結果是否為0即可。
字串轉數字也比較有技巧,以前我總是用atol這些函式,但是這樣有個壞處必須遍歷字串得到其始末位置才能擷取,這份程式碼用了另一個辦法。
但是我開始看到這個題的時候居然一點思路都沒有。回想以前做過的回溯題,八皇后,數學表示式,全排列都有一個特點,都是試圖枚舉出全部情況,只不過有些不合要求的情況被直接否了。這種列舉是層次性的,可以說是無限個迴圈,不是幾個迴圈可以寫出來的。 這道題,放的加號沒有限制,等號只能放一個。
先寫一個迴圈列舉等號的位置,然後就進入遞迴可以列舉加號的位置。
好好領會吧~
這裡有一些注意的地方。比如說判斷等式左右是否相等的方法是當進入等號右邊以後原和取其相反數,最後看結果是否為0即可。
字串轉數字也比較有技巧,以前我總是用atol這些函式,但是這樣有個壞處必須遍歷字串得到其始末位置才能擷取,這份程式碼用了另一個辦法。
比如說數字ABCD 其實就等於 ((A*10+B)*10+C)*10+D ,這樣可以邊遍歷邊計算。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; string str; int cnt=0; void dfs(int cur,int mid,int sum) { if(cur==str.size()) { if(sum==0) cnt++; return; } if(cur==mid) sum=-sum; int k,t=0; if(cur<mid) k=mid; else k=str.size(); for(int i=cur;i<k;++i) { t=t*10+str[i]-'0'; dfs(i+1,mid,sum+t); } } int main() { while(cin>>str&&str!="END") { cnt=0; for(int i=1;i<str.size();++i) dfs(0,i,0); cout<<cnt<<endl; } return 0; }