題目:
蜘蛛牌是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
思路:就是暴力搜尋嘗試,找出最短移動距離,中間有個用距離的一個小減值,我做這道時,本來想,這當移動時,把移動的那張牌的位置變成目前移到這張牌的位置,本來想着是可以,但是若這張牌上有多張牌時,隻改變了直接移動的那一張牌的位置,下面其他牌的位置沒有改變,這樣再進行一下運算時,一定出錯。直接來一次标記,找下一個可以直接移動的牌,i~j中的牌,都在j牌上;直接用j牌的位置,當做i+1牌的位置就行,其實不是當做,現在的狀況,本來就是;
代碼:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define Max 15
#define INF 0x3f3f3f3f
int pos[Max];
int book[Max];
int ans;
int flag;
void dfs(int d,int step)
{
if(step == 9)
{
ans = min(ans,d);
flag = 1;
return ;
}
for(int i = 1;i<=9;i++)
{
if(!book[i]) // 标記的意思是 還直接能不能用目前牌來移動。
{ // 沒有被标記,就是可以直接用目前牌來移動,也說明i+1牌一定可以放i這張牌
for(int j = i+1;j<=10;j++)
{
if(!book[j]) // 必須得标記,找下一可以直接移動的牌,i~j中的牌,都在j牌上;
{
int tt = abs(pos[i] - pos[j]);
if(d+tt>=ans) break;
book[i] = 1;
//int res = pos[i]; // 本來上面沒标記,就必須要把位置給改變了
//pos[i] = pos[j]; // 但是每一次移動都是職改變的剛移動的張牌的位置,
dfs(d+tt,step + 1); // 但那張牌下面的所有的位置都沒有改變,是以wrang anwer
book[i] = 0;
//pos[i] = res;
break;
}
}
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int k;
ans = INF;
memset(book,0,sizeof(book));
for(int i = 0;i<10;i++)
{
scanf("%d",&k);
pos[k] = i;
}
dfs(0,0);
printf("%d\n",ans);
}
return 0;
}