HDU-1584 蜘蛛牌(dfs)
可以多看看。
蜘蛛牌
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