這個題前幾天看了,想是要用動態規劃,當時沒想到好的動態轉移方程,就先放了放,不巧昨天晚上感冒了,今天拖着疲憊的身體作這個題,想仍是用枚舉吧,反正最大僅僅3^8=6561種狀況,確定不會超時的。思路就是枚舉數字之間的符號(「 」、「+」、「-」),而後對錶達式進行計算,能夠使用棧,數字棧中將中間有空格的兩個數或多個數計算成爲一個數,符號棧中去除空格字符,而後必然數字棧的元素比字符棧中元素數多1。從棧底向棧頂計算,b[i]和b[i+1]通過符號c[i]的運算,值保存在b[i+1]中,最後棧頂元素就是該表達式的計算結果,檢驗結果是否爲0,是0則將此完整的表達式化爲string類型存進set<string>中自動排序,最後輸出便可。ios
/* ID: jzzlee1 PROG:zerosum LANG:C++ */ //#include<iostream> #include<fstream> #include<cstring> #include<set> #include<string> using namespace std; ifstream cin("zerosum.in"); ofstream cout("zerosum.out"); set<string> set1; int main() { short n,d[10]; cin>>n; int a[10]={0,1,2,3,4,5,6,7,8,9},b[10]; int i; for(d[8]=0;n>=9?d[8]<=2:d[8]==0;++d[8]) for(d[7]=0;n>=8?d[7]<=2:d[7]==0;++d[7]) for(d[6]=0;n>=7?d[6]<=2:d[6]==0;++d[6]) for(d[5]=0;n>=6?d[5]<=2:d[5]==0;++d[5]) for(d[4]=0;n>=5?d[4]<=2:d[4]==0;++d[4]) for(d[3]=0;n>=4?d[3]<=2:d[3]==0;++d[3]) for(d[2]=0;d[2]<=2;++d[2]) for(d[1]=0;d[1]<=2;++d[1]) { int c[10]; for(i=0;i<=n;i++) { b[i]=i; c[i]=d[i]; } int j=1;int count=0; for(i=1;i!=n;++i) if(c[j]==1) ++j; else if(c[j]==2) ++j; else { count++; b[j]=10*b[j]+b[j+1]; for(int k=j;k<n-count;++k) { b[k+1]=b[k+2]; c[k]=c[k+1]; } } for(i=1;i!=n-count;++i) if(c[i]==1) b[i+1]+=b[i]; else b[i+1]=b[i]-b[i+1]; if(b[i]==0) { string str("1"); for(j=1;j!=n;j++) { switch(d[j]) { case 0: str+=" ";break; case 1: str+="+";break; case 2: str+="-";break; } str+=j+1+'0'; } set1.insert(str); } } set<string>::iterator iter; for(iter=set1.begin();iter!=set1.end();++iter) cout<<*iter<<endl; return 0; }