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 }

 

posted on 2012-08-30 22:46  wjinkun  阅读(108)  评论(0编辑  收藏  举报

导航