HDU1584 蜘蛛牌 DFS 简单题

题意:

蜘蛛牌是windows xp操作系统自带的一款纸牌游戏,游戏规则是这样的:只能将牌拖到比她大一的牌上面(A最小,K最大),如果拖动的牌上有按顺序排好的牌时,那么这些牌也跟着一起移动,游戏的目的是将所有的牌按同一花色从小到大排好,为了简单起见,我们的游戏只有同一花色的10张牌,从A到10,且随机的在一行上展开,编号从1到10,把第i号上的牌移到第j号牌上,移动距离为abs(i-j),现在你要做的是求出完成游戏的最小移动距离。

输入:

第一个输入数据是T,表示数据的组数。
每组数据有一行,10个输入数据,数据的范围是[1,10],分别表示A到10,我们保证每组数据都是合法的。

输出:

对应每组数据输出最小移动距离。

a[i] 表示编号为i的牌放在了a[i]这个位置上

b[i] 存储a[i]最原先的位置,便于回溯

分析:最后一定是移动了9次牌的位置(每个一次),因为10号牌是不需要移动的

   若vis[i]=false,则第i号牌没有移动过,则a[i]一定等于b[i]

   若vis[i]=true,则第i号牌移动过,a[i]不等于b[i]

这道题有一个要注意的地方:

在把i放到i+1下面的时候,a[i]=a[i+1],

但此时跟着第i号牌的牌也要同时=a[i+1],所以回溯的时候也要把他们恢复过来

而且比如说4要移到5的位置上,假设5在这之前已经移到了6的上面,那4就要移到6的位置上,而不是5的位置

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 using namespace std;
 5 const int inf=0x3f3f3f3f;
 6 bool vis[12];
 7 int n;
 8 int ans;
 9 int a[12];
10 int b[12];
11 void dfs(int cnt,int sum,int dep)
12 {
13     vis[cnt]=true;
14     for(int j=1;j<=cnt;j++)
15         if(a[j]==b[cnt])
16             a[j]=a[cnt+1];
17     if(dep==9&&sum<ans)
18     {
19         ans=sum;
20         return ;
21     }
22     if(sum>=ans||dep==9)
23         return ;
24
25     for(int i=1;i<10;i++)
26     {
27         if(!vis[i])
28         {
29             dfs(i,sum+abs(a[i]-a[i+1]),dep+1);
30             vis[i]=false;
31             for(int j=1;j<=i;j++)
32                 if(a[j]==a[i+1])
33                     a[j]=b[i];
34         }
35     }
36     return ;
37 }
38 int main()
39 {
40     int test;
41     scanf("%d",&test);
42     while(test--)
43     {
44         int u,w=1;
45         for(int i=1;i<=10;i++)
46         {
47             scanf("%d",&u);
48             a[u]=w++;
49         }
50         for(int i=1;i<=10;i++)
51             b[i]=a[i];
52         ans=inf;
53         memset(vis,false,sizeof(vis));
54         for(int i=1;i<10;i++)
55         {
56             dfs(i,abs(a[i]-a[i+1]),1);
57             vis[i]=false;
58             a[i]=b[i];
59
60         }
61         printf("%d\n",ans);
62     }
63     return 0;
64 }

时间: 2024-10-25 10:09:08

HDU1584 蜘蛛牌 DFS 简单题的相关文章

ACM学习历程—HDU1584 蜘蛛牌(动态规划 &amp;&amp; 状态压缩)

Description 蜘蛛牌是windows xp操作系统自带的一款纸牌游戏,游戏规则是这样的:只能将牌拖到比她大一的牌上面(A最小,K最大),如果拖动的牌上有按顺序排好的牌时,那么这些牌也跟着一起移动,游戏的目的是将所有的牌按同一花色从小到大排好,为了简单起见,我们的游戏只有同一花色的10张牌,从A到10,且随机的在一行上展开,编号从1到10,把第i号上的牌移到第j号牌上,移动距离为abs(i-j),现在你要做的是求出完成游戏的最小移动距离. Input 第一个输入数据是T,表示数据的组数.

HDU1584(蜘蛛牌)

蜘蛛牌 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2880    Accepted Submission(s): 1230 Problem Description 蜘蛛牌是windows xp操作系统自带的一款纸牌游戏,游戏规则是这样的:只能将牌拖到比她大一的牌上面(A最小,K最大),如果拖动的牌上有按顺序排好的牌时,那么这些牌也

HDU1241&amp;POJ2386 dfs简单题

2道题目都差不多,就是问和相邻所有点都有相同数据相连的作为一个联通快,问有多少个连通块 因为最近对搜索题目很是畏惧,总是需要看别人代码才能上手,就先拿这两道简单的dfs题目来练练手,顺便理一理dfs的思路,分析清楚dfs的退出递归的条件和什么时候进行递归调用是至关重要的,这两道题目不涉及回溯,对于需要回溯的题目也要清楚分析,找到回溯条件,在对一个新的状态dfs时,后面加上回溯的语句 HDU1241代码: 1 #include <cstdio> 2 #include <cstring>

HDU1016 Prime Ring Problem DFS 简单题

题意:输入n,代表有一个n个节点的环,然后在节点分别填入1到n这n个数,规定,第一个填入的必须是1. 0<n<40 要求填入后满足,任意相邻的2个节点的数之和为素数. 将满足条件的填法按照字典序的顺序小到大依次输出. 其实刚开始做的时候我觉得这道题会做很久的,想好后就开始打了,打着打着发现这道题打好了,有点意外,原来这么简单. 注意回溯,在每次DFS后要记得把状态恢复原样,比如这道题是每次DFS后都要把当前DFS的数字i恢复为vis[i]=false; 先考虑好初始化,结束条件,回溯. 先来一

HDU 1584(蜘蛛牌 DFS)

题意是在蜘蛛纸牌的背景下求 10 个数的最小移动距离. 在数组中存储 10 个数字各自的位置,用深搜回溯的方法求解. 代码如下: 1 #include <bits/stdc++.h> 2 using namespace std; 3 int ans,a[20]; 4 bool vis[20]; 5 void dfs(int num,int sum) 6 { 7 if(sum > ans) return; 8 if(num == 9) 9 { 10 ans = sum; 11 return

LeetCode Generate Parentheses 构造括号串(DFS简单题)

题意: 产生n对合法括号的所有组合,用vector<string>返回. 思路: 递归和迭代都可以产生.复杂度都可以为O(2n*合法的括号组合数),即每次产生出的括号序列都保证是合法的. 方法都是差不多的,就是记录当前产生的串中含有左括号的个数cnt,如果出现右括号,就将cnt--.当长度为2*n的串的cnt为0时,就是答案了,如果当前cnt比剩下未填的位数要小,则可以继续装“(”,否则不能再装.如果当前cnt>0,那么就能继续装“)”与其前面的左括号匹配(无需要管匹配到谁,总之能匹配)

HDU 1010 Tempter of the Bone DFS 简单题 注意剪枝

题意:一只小狗要刚好在t时刻从起点都到终点,问可不可以. 注意剪枝. 1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 using namespace std; 5 int maze[9][9]; 6 bool vis[9][9]; 7 int n,m,t; 8 bool ans; 9 struct Point 10 { 11 int x,y; 12 }; 13 int dx[4]={0,0,-1,1}

HDU 1258 Sum It Up DFS 简单题 好题

给出一个数t,n,然后后面有n个数. 问:从这n个数里面能不能挑出一些数,使得和为t,注意输出顺序. Sample Input 4 6 4 3 2 2 1 1 5 3 2 1 1 400 12 50 50 50 50 50 50 25 25 25 25 25 25 0 0 Sample Output Sums of 4: 4 3+1 2+2 2+1+1 Sums of 5: NONE Sums of 400: 50+50+50+50+50+50+25+25+25+25 50+50+50+50+5

HDU 1175 连连看 DFS 简单题

Problem Description “连连看”相信很多人都玩过.没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子.如果某两个相同的棋子,可以通过一条线连起来(这条线不能经过其它棋子),而且线的转折次数不超过两次,那么这两个棋子就可以在棋盘上消去.不好意思,由于我以前没有玩过连连看,咨询了同学的意见,连线不能从外面绕过去的,但事实上这是错的.现在已经酿成大祸,就只能将错就错了,连线不能从外围绕过.玩家鼠标先后点击两块棋子,试图将他们消去,然后游戏的后台判断这两个方格能