蜘蛛牌
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2358 Accepted Submission(s):
1012
传送门
Problem Description
蜘蛛牌是windows
xp操作系统自带的一款纸牌游戏,游戏规则是这样的:只能将牌拖到比她大一的牌上面(A最小,K最大),如果拖动的牌上有按顺序排好的牌时,那么这些牌也跟着一起移动,游戏的目的是将所有的牌按同一花色从小到大排好,为了简单起见,我们的游戏只有同一花色的10张牌,从A到10,且随机的在一行上展开,编号从1到10,把第i号上的牌移到第j号牌上,移动距离为abs(i-j),现在你要做的是求出完成游戏的最小移动距离。
Input
第一个输入数据是T,表示数据的组数。
每组数据有一行,10个输入数据,数据的范围是[1,10],分别表示A到10,我们保证每组数据都是合法的。
每组数据有一行,10个输入数据,数据的范围是[1,10],分别表示A到10,我们保证每组数据都是合法的。
Output
对应每组数据输出最小移动距离。
Sample Input
1
1 2 3 4 5 6 7 8 9 10
Sample Output
9
MY CODE:
1 /******************************* 2 3 Date : 2015-12-06 21:05:48 4 Author : WQJ (1225234825@qq.com) 5 Link : http://www.cnblogs.com/a1225234/ 6 Name : 7 8 ********************************/ 9 #include <iostream> 10 #include <cstdio> 11 #include <algorithm> 12 #include <cmath> 13 #include <cstring> 14 #include <string> 15 #include <set> 16 #include <vector> 17 #include <queue> 18 #include <stack> 19 #define LL long long 20 using namespace std; 21 struct nod 22 { 23 bool f; 24 int s,e; 25 }a[11]; 26 int k; 27 int m=0; 28 int minstep=1000000; 29 int co=0; 30 void dfs(int step) 31 { 32 int i,j; 33 if(step>minstep) return; 34 if(a[k].s==1) 35 { 36 if(step<minstep) 37 minstep=step; 38 return; 39 } 40 for(i=1;i<=10;i++) 41 { 42 if(a[i].e==10||a[i].f==0) continue; 43 for(j=1;j<=10;j++) 44 { 45 if(a[j].f&&i!=j&&a[i].e==(a[j].s-1)) 46 { 47 a[j].s=a[i].s; 48 a[i].f=0; 49 dfs(step+abs(i-j)); 50 a[j].s=a[i].e+1; 51 a[i].f=1; 52 break; 53 } 54 } 55 } 56 return; 57 } 58 int main() 59 { 60 freopen("in.txt","r",stdin); 61 int T; 62 int i,j; 63 cin>>T; 64 while(T--) 65 { 66 minstep=10000; 67 for(i=1;i<=10;i++) 68 { 69 cin>>a[i].s; 70 a[i].e=a[i].s; 71 a[i].f=1; 72 if(a[i].s==10) 73 k=i; 74 } 75 for(i=1;i<=10;i++) 76 { 77 if(a[i].e==10||a[i].f==0) continue; 78 for(j=1;j<=10;j++) 79 if(a[j].f==1&&i!=j&&a[i].e==(a[j].s-1)) 80 { 81 a[j].s=a[i].s; 82 a[i].f=0; 83 dfs(abs(i-j)); 84 a[j].s=a[i].e+1; 85 a[i].f=1; 86 break; 87 } 88 } 89 cout<<minstep<<endl; 90 } 91 return 0; 92 }
百度的别的精简代码,数组存放的是位置,下标是牌。
1 #include <iostream> 2 using namespace std; 3 int s,x[11],visit[11]; 4 int cmp(int a,int b) //求绝对值 5 { 6 return a>b?a-b:b-a; 7 } 8 void dfs(int n,int step) 9 { 10 int i,j,k; 11 if(n==9) 12 { 13 if(step<s)s=step; 14 return; 15 } 16 for(i=0;i<10;i++) //用来移动的牌 17 if(!visit[i]) 18 for(j=i+1;j<10;j++) //移动到那个位置 19 { 20 if(!visit[j]) 21 { 22 k=step+cmp(x[i],x[j]); 23 if(k>=s)break; //如果还没到终点就已经比先前的方案步数多,那么直接over 24 visit[i]=1; //标记当前移动的牌已经就位了,因为i到了j的位置了,那么移动j就不管i的鸟事了 25 dfs(n+1,k); 26 visit[i]=0; 27 break; 28 } 29 } 30 } 31 int main (void) 32 { 33 freopen("in.txt","r",stdin); 34 int i,j,k,l,n,a; 35 cin>>n; 36 while(n--) 37 { 38 for(i=0;i<10;i++) 39 cin>>a,x[a-1]=i,visit[i]=0; //用x记录每个牌出现的位置 40 s=999999999; 41 dfs(0,0); 42 cout<<s<<endl; 43 } 44 return 0; 45 }