标签:style blog http io ar color os sp for
题意:
给出一个数T,再给出n个数。若n个数中有几个数(可以是一个)的和是T,就输出相加的式子。不过不能输出相同的式子。
分析:
运用的是回溯法。比较特殊的一点就是不能输出相同的式子。这个可以通过map来实现:map<string,int>把字符串(可以是C语言的字符串)和整数联系起来了。我们可以把相加起来的几个数变成一个字符串(2+1+1,变成“211”),如果它出现过,就标记为1,初始值是0。出现过的就不再输出了。
剪枝:
1、所有的数加起来的和小于T,直接输出NONE。
2、搜索过程中,发现sum大于t,直接return ,不再继续搜索了。如果sum等于t,验证有无重复后决定输出与否,也不再继续搜索了。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<algorithm> 6 #include<map> 7 using namespace std; 8 9 const int N=13; 10 int t,n,flag,sum; 11 int p[N]; 12 bool vis[N]; 13 map<string,int> st; 14 char ch[30]; 15 void DFS(int k) 16 { 17 if(sum==t) 18 { 19 int j=0; 20 for(int i=0;i<n;i++) 21 { 22 if(!vis[i]) continue; 23 int x=p[i]; 24 while(x) 25 { 26 int y=x%10; 27 ch[j++]=y+48; 28 x/=10; 29 } 30 } 31 ch[j]=0; 32 if(!st[ch]) 33 { 34 //puts(ch); 35 flag=1; 36 int f=0; 37 for(int i=0;i<n;i++) 38 { 39 if(vis[i]&&f) printf("+%d",p[i]); 40 if(vis[i]&&!f) {printf("%d",p[i]);f=1;} 41 } 42 printf("\n"); 43 st[ch]=1; 44 return ; 45 } 46 47 } 48 if(sum>t) return ; 49 for(int i=k;i<n;i++) 50 { 51 sum+=p[i]; 52 vis[i]=1; 53 DFS(i+1); 54 sum-=p[i]; 55 vis[i]=0; 56 } 57 } 58 int main() 59 { 60 //freopen("test.txt","r",stdin); 61 while(scanf("%d%d",&t,&n)!=EOF&&t) 62 { 63 st.clear(); 64 printf("Sums of %d:\n",t); 65 for(int i=0;i<n;i++) 66 { 67 scanf("%d",&p[i]); 68 sum+=p[i]; 69 } 70 if(sum<t) {printf("NONE\n");continue;} 71 memset(vis,0,sizeof(vis)); 72 flag=0; 73 sum=0; 74 DFS(0); 75 if(!flag) printf("NONE\n"); 76 } 77 return 0; 78 }
标签:style blog http io ar color os sp for
原文地址:http://www.cnblogs.com/Potato-lover/p/4113625.html