【USACO2.3.3】和为零
Time Limit:10000MS Memory Limit:65536K
Total Submit:9 Accepted:5
Case Time Limit:1000MS
Description
请考虑一个由 1 到 N ( N=3, 4, 5 ... 9 )的数字组成的递增数列:1 2 3 ... N。现在请在数列中插入“+”表示加,或者“-”表示减,抑或是“ ”表示空白,来将每一对数字组合在一起(请不在第一个数字前插入符号)。计算该表达式的结果并注意你是否得到了和为零。
请你写一个程序找出所有产生和为零的长度为N的数列。
Input
单独的一行表示整数N (3 <= N <= 9)。
Output
按照ASCII码的顺序,输出所有在每对数字间插入“+”, “-”, 或 “ ”后能得到和为零的数列。(注意:就算两个数字之间没有插入符号也应该保留空格)
Sample Input
7
Sample Output
1+2-3+4-5-6+7
1+2-3-4+5+6-7
1-2 3+4+5+6+7
1-2 3-4 5+6 7
1-2+3+4-5+6-7
1-2-3-4-5+6+7
简单 的 DFS。。但是输出搞错了 一次。代码写的超烂。
下面是 AC代码 :
#include<iostream> #include<algorithm> using namespace std; int a[10]={0,1,2,3,4,5,6,7,8,9}; int b[10]; //1代表“ ”空格,2代表+,3代表-。 int ans[10]; int n,i,j; int ans_n; int ans_val[1000]; void dfs(int cur){ if(cur==n){ int now=0,temp=1; int k=1; for(i=1;i<=n-1;i++){ if(b[i]==1){ if(temp>=0) temp=temp*10+(i+1); else temp=temp*10-(i+1); } else if(b[i]==2){ ans[k++]=temp; temp=i+1; } else if(b[i]==3){ ans[k++]=temp; temp=-(i+1); } } ans[k]=temp; for(i=1;i<=k;i++) now+=ans[i]; if(now==0){ int s=0; for(i=1;i<=n-1;i++) s=s*10+b[i]; ans_val[ans_n++]=s; } return ; } b[cur]=1; dfs(cur+1); b[cur]=2; dfs(cur+1); b[cur]=3; dfs(cur+1); } int main(){ int temp[10]; cin>>n; dfs(1); sort(ans_val,ans_val+ans_n); for(i=0;i<ans_n;i++){ cout<<1; int l=1,t=ans_val[i]; while(t){ temp[l++]=t%10; t/=10; } for(j=n-1;j>=1;j--){ if(temp[j]==1) cout<<" "<<n-j+1; else if(temp[j]==2) cout<<"+"<<n-j+1; else if(temp[j]==3) cout<<"-"<<n-j+1; } cout<<endl; } return 0; }