蜘蛛牌 HDU - 1584
蜘蛛牌
蜘蛛牌是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 10Sample Output
9题解+解析:
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;
int a[15];
bool visit[15];
int ans;
void dfs(int num, int sum)
{
if (sum >= ans)
{
return; // 不是最优,剪枝。
}
if (num == 9)//移9次说明已经完成排列了。
{
ans = sum;
}
for (int i = 1; i < 10; i++)//确定需要移的数i。
{
if (!visit[i])
{
visit[i] = true;//i被移走了,所以数字i的位置设为被访问过,也就是说该位置没有数字。
for (int j = i+1; j < 11; j++)//确定被移到的数j(j至少比i大1)。也有可能j比i大很多,例如把1移到5的下面。1没有访问过,2,3,4却访问过,说明2,3,4都在5的下面,所以可以把1移到5的下面。
{
if (!visit[j])
{
dfs(num+1, sum+abs(a[i]- a[j]));//操作数等于位置差的绝对值。
break;
}
}
visit[i] = false;//回溯到i没有被移走的状态。
}
}
}
int main()
{
int n;
scanf("%d", &n);
while (n--)
{
ans = 0x7f7f7f7f;
memset(visit, 0, sizeof(visit));
for (int i = 1; i <= 10 ;i++)
{
int temp;
scanf("%d", &temp);
a[temp] = i;//确定temp这个数在第i个位置
}
dfs(0, 0);
printf("%d\n", ans);
}
return 0;
}