Seven Puzzle
Time Limit : 1 sec, Memory Limit : 65536 KBSeven Puzzle
7パズルは8つの正方形のカードとこれらのカードがぴたりと収まる枠を使って行います。それぞれのカードは互いに区別できるように、0,1,2....7と番号がつけられています。枠には、縦に2個、横に4個のカードを並べることができます。
7パズルを始めるときには、まず枠にすべてのカードを入れます。枠のなかで0のカードだけは、上下左右に隣接するカードと位置を交換することができます。たとえば、枠の状態が図( a )のときに、0のカードの右に隣接した、7のカードと位置を交換すれば、図( b )の状態になります。あるいは、図( a )の状態から0のカードの下に隣接した2のカードと位置を交換すれば図( c )の状態になります。カードの位置を入れ替える操作はこれだけが許されます。図( a )の状態で0のカードと上下左右に隣接するカードは7と2のカードだけなので、これ以外の位置の入れ替えは許されません。
ゲームの目的は、カードをきれいに整列して図( d )の状態にすることです。最初の状態を入力とし、カードをきれいに整列するまでに、必要な最小手数を出力して終了するプログラムを作成してください。ただし、入力されたカードの状態からは図( d )の状態に移ることは可能であるとします。
入力データは、1行に8つの数字が与えられます。これらは、最初の状態のカードの並びを表します。図( a )の数字表現は0,7,3,4,2,5,1,6に、図( c )は2,7,3,4,0,5,1,6となります。
![]() | ![]() |
図( a ) 0,7,3,4,2,5,1,6の場合 | 図( b ) 7,0,3,4,2,5,1,6の場合 |
---|
![]() | ![]() |
図( c ) 2,7,3,4,0,5,1,6の場合 | 図( d ) 0,1,2,3,4,5,6,7(最終状態) |
---|
Input
1つ目のパズルの状態(整数;空白区切り) 2つ目のパズルの状態(整数;空白区切り) : :
与えられるパズルの数は1000以下です。
Output
1つ目のパズルの状態から最終状態へ移行する最小手数(整数) 2つ目のパズルの状態から最終状態へ移行する最小手数(整数) : :
Sample Input
0 1 2 3 4 5 6 7 1 0 2 3 4 5 6 7 7 6 5 4 3 2 1 0
Output for the Sample Input
0 1 28
输入:多组输入,每组8个数,表示初始状态前四个数为第一行从左到右,后四个数为第二行从左到右。
输出:至少需要多少步可以从输入状态到达最终状态(0 1 2 3 4 5 6 7)
#include<iostream>
#include<map>
#include<string>
#include<queue>
#include<algorithm>
using namespace std;
typedef pair<string, int> P;
map<string, int> dp;
short op[4] = {-4, 4, -1, 1};
string a;
int bfs();
int solve();
int main()
{
while(getline(cin, a))
cout<<solve()<<endl;
return 0;
}
int bfs()
{
queue<P> q;
P p, temp, now;//表示起始序列为"01234567",并且目前0所在的位置为0
dp["01234567"] = 0;
q.push(P("01234567", 0));//把起始点放入队列中
while(!q.empty()){
temp = q.front();
q.pop();
int cur = temp.second;
for(int i = 0; i < 4; i++){
int next = cur + op[i];
string str = temp.first;//将队头元素的string赋值给str
swap(str[cur], str[next]);//交换两个元素的位置
map<string, int>::iterator it = dp.find(str);//在map中找str字符串
if(next >= 0 && next < 8 && !(cur == 3 && next == 4) && !(cur == 4 && next == 3) && it == dp.end()){
now.first = str; now.second = next;
dp[now.first] = dp[temp.first] + 1;
q.push(now);
}
}
}
/*map<string, int>::iterator it = dp.begin();
while(it != dp.end()){
cout<<(it->first)<<'\t'<<(it->second)<<endl;
it++;
} */
return -1;
}
int solve()
{
a.erase(remove(a.begin(), a.end(), ' '), a.end());
bfs();
return dp[a];
}