話說鄙人做這道題都有種把翔都做出來的感覺,主要是死在對string(一個自己不是很懂的東西)的不瞭解。然後一直在調bug,題意就是給你一個8宮格,然後0表示空缺,可以將相鄰位的數字與空缺交換,以表示將該數字塊移到空缺,然後會給你多組輸入,每一組表示按從左到右,從上到下排列的8個數,問將這樣排列的8個數移成01234567,最少移動多少步。輸入有多組。先開始老老實實按題意從出發點開始移動,寫完跑了一組就慢的不行了,再這玩意又是多組輸入,所以從它給的輸入開始搜,那豈不是超時妥妥的,後來看了下題解,才發現是要反的搞,何爲反的搞,就是以01234567爲出發點來BFS所有的可能,然後直接查找。這樣搜一遍就OK了。
主要蛋疼的是我用了string,先開始一直沒對string初始化,也就是一開始只寫了string s;而沒有像下面的代碼一樣寫成string s = "00000000"(切記此時一定要是8個數,無論這8個數是幾都行,但一定要8個數,我這裏就直接用了8個0),這樣沒初始化s的話,s默認是沒有長度的,但是訪問它的單個節點位置確實行的通的,比如訪問是s[0],s[1],之類的是可以查看的,雖然這是非法的。但編譯器還是會讓你過,因爲string是一個封裝好的類,它是一棵樹,有上限空間,這是事先開闢好的,但是並不能訪問,或者說訪問是非法的。只有當你初始化了一定空間,這段被初始化的空間訪問纔是合法的,所以當你直接調用s時,若沒初始化是得不到正確結果的。此題給的數量是8個數,所以應該初始8個字符大小的合法空間。爲了這個問題,調了將近兩個小時也是沒誰了,,,,以後還是多多注意的好。。。。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#include<algorithm>
#include<map>
#include<string>
using namespace std;
map<string,int>mp;
queue<string>q;
int mov[4]= {-1,1,-4,4};
void bfs()
{
mp.clear();
mp["01234567"]=1;
q.push("01234567");
while(!q.empty())
{
string s=q.front();
q.pop();
int f=0;
for(int i=0; i<8; i++)
if(s[i]=='0')
{
f=i;
break;
}
for(int i=0;i<4;i++)
{
if(f+mov[i]<0||f+mov[i]>7||(f+mov[i]==4&&i==1)||(f+mov[i]==3&&i==0))continue;
string t=s;
swap(t[f],t[f+mov[i]]);
if(mp[t]==0)
{
mp[t]=mp[s]+1;
//cout<<t<<' '<<mp[t]<<endl;
q.push(t);
}
}
}
}
int main()
{
//freopen("in.in","r",stdin);
bfs();
int t;
string s="00000000";
while(scanf("%d",&t)!=EOF)
{
s[0]=t+'0';
for(int i=1;i<8;i++)
{
scanf("%d",&t);
s[i]=t+'0';
}
/*for(int i=0;i<8;i++)
printf("%c",s[i]);
printf("\n");*/
//cout<<s<<endl;
printf("%d\n",mp[s]-1);
}
return 0;
}