首页 > 技术文章 > HDU-1584 蜘蛛牌(dfs)

cancangood 2013-08-16 16:16 原文

 可以多看看。

                                          蜘蛛牌

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1206    Accepted Submission(s): 476

Problem Description
蜘蛛牌是windows xp操作系统自带的一款纸牌游戏,游戏规则是这样的:只能将牌拖到比她大一的牌上面(A最小,K最大),如果拖动的牌上有按顺序排好的牌时,那么这些牌也跟着一起移动,游戏的目的是将所有的牌按同一花色从小到大排好,为了简单起见,我们的游戏只有同一花色的10张牌,从A到10,且随机的在一行上展开,编号从1到10,把第i号上的牌移到第j号牌上,移动距离为abs(i-j),现在你要做的是求出完成游戏的最小移动距离。
 
Input
第一个输入数据是T,表示数据的组数。 每组数据有一行,10个输入数据,数据的范围是[1,10],分别表示A到10,我们保证每组数据都是合法的。
 
Output
对应每组数据输出最小移动距离。
 
Sample Input
1
1 2 3 4 5 6 7 8 9 10
 
Sample Output
9
 
Author
xhd
 
Source
 
Recommend
lcy
 1 //此题目,有几个值得学习的地方,一:i和x的互换。二是ans,没有ans就不行,不知道什么原因。
 2 #include<stdio.h>
 3 #include<math.h>
 4 int visit[20],a[20],ans;
 5 void dfs(int t,int sum)//t代表已经移动了几张牌,sum代表目前移动耗费的步数
 6 {
 7     int i,j;
 8    if(sum>=ans)return;//这个剪枝是为什么要这样做,我还是搞不懂.
 9     if(t==9)//只用移动9次 10是固定不变的
10     {
11         ans=sum;
12         return;
13     }
14     for(i=1;i<10;i++)
15     {
16         if(visit[i]==0)
17         {
18             visit[i]=1;//标记用过了。
19             for(j=i+1;j<=10;j++)//这个用来确定i牌要移到什么位置
20             {
21                 if(visit[j]==0)//比如要移1了,如果2,3,4,5都已经被移动过了 那么这几张牌必定叠放在6的下面,所以要移到6的位置
22                 { 
23                     dfs(t+1,sum+abs(a[j]-a[i]));
24                            break;
25                 }
26             }
27             visit[i]=0;//这里回溯
28         }
29     }
30 }
31 int main()
32 {
33    int n,i,x;
34    scanf("%d",&n);
35    while(n--)
36    {
37        for(i=0;i<10;i++)
38        {
39            scanf("%d",&x);
40            a[x]=i;//一:牌面为i的牌所在的位置
41            visit[i]=0;
42        }
43       ans=1000000;//为什么要这样定义ans;
44       dfs(0,0);
45         printf("%d\n",ans);
46    }
47    return 0;
48 }
49 
50           
第一次做的时候,我理解题意是: 先找到牌1再找牌2.。。一直找到牌10 所以我的代码:
就总是wa了,我犯的错误如下:
 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<math.h>
 4 int vist[20];
 5 int a[20];
 6 int s;
 7 void dfs(int i)
 8 {
 9     int j,f;
10     for(j=0;j<10;j++)
11     {
12         if(a[j]-1==a[i]&&vist[j]==0)
13         {
14             vist[j]=1;
15                f=j;
16             s+=abs(i-j);
17              dfs(f);
18              vist[j]=0;
19         }
20     }
21 }
22 int main()
23 {
24     int t,i;
25     scanf("%d",&t);
26     while(t--)
27     {
28         s=0;
29         memset(vist,0,sizeof(vist));
30         for(i=0;i<10;i++)
31             scanf("%d",&a[i]);
32         for(i=0;i<10;i++)
33             if(a[i]==1)
34                 dfs(i);
35        printf("%d\n",s);
36      }
37     return 0;
38 }
39 
40 
41 
42 
43              

 



 

 

推荐阅读