/* 这个代码运行的时间长主要是因为每次枚举之后都要重新计算一下和的值! 如果要快的话,应该在dfs,也就是枚举的过程中计算出前边的数值,知道最后,这样不必每一次枚举都要从头再算一遍值! */ 1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 using namespace std; 6 7 char ch[20]; 8 char sign[3]={‘+‘, ‘-‘, ‘.‘}; 9 int n, cnt; 10 int num[20]; 11 int signNum[200]; 12 13 void dfs(int u){ 14 if(u==n){ 15 if(signNum[‘+‘]==n-1 || signNum[‘+‘]+signNum[‘.‘]==n-1 || signNum[‘.‘]==n-1 || signNum[‘-‘]==n-1) return; 16 for(int i=1; i<n; ++i){ 17 num[i]=i; 18 if(ch[i]==‘.‘){ 19 int s=i, v=i; 20 while(i<n && ch[i]==‘.‘){ 21 if(i+1>9) 22 s=s*100+(++i); 23 else s=s*10+(++i); 24 } 25 if(s>10000) return ;//非得加上这句话....然后就幸运的过了! 26 num[v]=s; 27 --i; 28 } 29 } 30 num[n]=n; 31 int s=num[1]; 32 for(int i=1; i<n; ++i) 33 if(ch[i]!=‘.‘){ 34 if(ch[i]==‘+‘) s+=num[i+1]; 35 else s-=num[i+1]; 36 } 37 if(s==0){ 38 ++cnt; 39 if(cnt<=20){ 40 for(int i=1; i<n; ++i) 41 printf("%d %c ", i, ch[i]); 42 printf("%d\n", n); 43 } 44 } 45 return; 46 } 47 for(int i=0; i<3; ++i){ 48 ch[u]=sign[i]; 49 ++signNum[sign[i]]; 50 dfs(u+1); 51 --signNum[sign[i]]; 52 } 53 } 54 55 int main(){ 56 while(scanf("%d", &n)!=EOF){ 57 cnt=0; 58 dfs(1); 59 printf("%d\n", cnt); 60 } 61 return 0; 62 }
时间: 2024-10-15 00:55:16