POJ1011-搜索
这道题做了一天,快烦死了。。。。。。。。
第一次是自己写的代码,思路和别人的不太一样,一般的测试数据可以,碰到那些35个数以上的半天不出结果,最后写第二种方法的时候发现我这个方法无法去掉相同数字的情况,所以非常非常慢。
1 #include <stdio.h> 2 3 int part[65]; //最多64个stick parts 4 int length[64]; //原始的stick length 5 int number; //原始的stick number 6 int n; //输入n个 7 int sum; //总长度 8 9 int dfs(int i) 10 { 11 int j,flag=1; 12 if(i==n+1) 13 return 1; 14 for(j=0; flag&&j<number; j++) 15 { 16 if(part[i]>sum/number-length[j]) 17 continue; 18 else if(length[j]==0) 19 flag=0; 20 length[j]+=part[i]; 21 if(length[j]==sum/number) 22 flag=0; 23 else if(sum/number-length[j]<part[n]) 24 { 25 length[j]-=part[i]; 26 continue; 27 } 28 if(dfs(i+1)) 29 return 1; 30 else 31 length[j]-=part[i]; 32 } 33 return 0; 34 } 35 36 37 int main() 38 { 39 int i,j; 40 //freopen("input.txt","r",stdin); 41 while(scanf("%d",&n),n) 42 { 43 //插入排序 求和 44 for(sum=0,i=1; i<=n; i++) 45 { 46 scanf("%d",&part[0]); 47 j=i-1; 48 while(j>0&&part[0]>part[j]) 49 part[j+1]=part[j--]; 50 part[j+1]=part[0]; 51 sum+=part[0]; 52 } 53 //dfs 54 for(number=sum/part[1]; number>=1; number--) 55 { 56 if(sum%number) 57 continue; 58 for(i=0; i<number; i++) 59 length[i]=0; 60 if(dfs(1)) 61 break; 62 } 63 printf("%d\n",sum/number); 64 } 65 return 0; 66 }
第二次参考别人的,问题的关键还是剪枝:
1.一次搜索不成功时,下次跳过相同的(非常关键,不加这个也是要等半天才出结果);
2.若搜索长木棒的第一个小棒时若不成功立即return,排除这种length;
3.若一个小木棒正好可以构成长木棒的最后一块,但下一次搜索不成功也立即return;
Problem: 1011 | User: wjinkun | |
Memory: 372K | Time: 16MS | |
Language: GCC | Result: Accepted |
1 #include <stdio.h> 2 3 int part[65][2]; //最多64个stick parts 4 int number; //原始的stick number 5 int n; //输入n个 6 int length; //原始长度 7 int sum; 8 9 int dfs(int l,int i) 10 { 11 int j,temp=0; 12 if(i==n) 13 return 1; 14 for(j=1;j<=n;j++) 15 { 16 if(part[j][1]==0) 17 { 18 if(l+part[j][0]<=length&&temp!=part[j][0]) 19 { 20 temp=part[j][0]; 21 part[j][1]=1; 22 if(dfs((l+part[j][0])%length,i+1)) 23 return 1; 24 part[j][1]=0; 25 if(l==0||length-l==part[j][0]) 26 return 0; 27 } 28 } 29 } 30 return 0; 31 } 32 33 int main() 34 { 35 int i,j; 36 // freopen("input.txt","r",stdin); 37 while(scanf("%d",&n),n) 38 { 39 //插入排序 求和 40 for(sum=0,i=1; i<=n; i++) 41 { 42 scanf("%d",&part[0][0]); 43 j=i-1; 44 while(j>0&&part[0][0]>part[j][0]) 45 part[j+1][0]=part[j--][0]; 46 part[j+1][0]=part[0][0]; 47 sum+=part[0][0]; 48 part[i][1]=0; 49 } 50 //dfs 51 for(length=part[1][0]; ; length++) 52 { 53 if(sum%length==0) 54 { 55 if(dfs(0,0)) 56 break; 57 } 58 } 59 printf("%d\n",length); 60 } 61 return 0; 62 }