先上题目:
蜘蛛牌
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1303 Accepted Submission(s): 512
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
搜索题,题意中文不解释,一开始想到用bfs,结果爆内存了= =,后来在网上看了一下别人的做法= =。大概如下:
首先需要分析,这个游戏操作上的特点:
①一定是小牌往大牌上移动。
②可能把不同的牌当成小牌作为开始移动的第一张
③有很多种移动的顺序,但是我们要找的是总距离最小的一种,所以我们要枚举,但是也要剪枝
④在枚举过程中遇到距离大于记录的最小距离的时候可以直接剪去。
总的来说还是对dfs的题目不是很熟练······
上代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 #include <queue> 5 #define MAX 11 6 #define INF 100000000 7 using namespace std; 8 9 int loc[MAX]; 10 bool vis[MAX]; 11 int dist; 12 13 void dfs(int cns,int temp){ 14 if(temp>=dist) return ; 15 if(cns==9){ 16 dist=temp; 17 return; 18 } 19 for(int i=1;i<=10;i++){ 20 if(!vis[i]){ 21 for(int j=i+1;j<=10;j++){ 22 if(!vis[j]){ 23 vis[i]=1; 24 dfs(cns+1,temp+abs(loc[i]-loc[j])); 25 break; 26 } 27 } 28 vis[i]=0; 29 } 30 } 31 } 32 33 int main() 34 { 35 int t; 36 //freopen("data.txt","r",stdin); 37 scanf("%d",&t); 38 while(t--){ 39 int n; 40 for(int i=1;i<=10;i++){ 41 scanf("%d",&n); 42 loc[n]=i; 43 } 44 dist=INF; 45 memset(vis,0,sizeof(vis)); 46 dfs(0,0); 47 printf("%d ",dist); 48 } 49 return 0; 50 }