poj 1077八数コード問題+康托展開+bfs
新年の第一題は、こんなに長く引きずってやっとできた.
//============================================================================
//
// > File : poj1077.cpp
// > Author : flowertree
// > Time : 2016 1 16
// > Algorithm : + + bfs
//
//============================================================================
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
using namespace std;
#define MAX 1000005
struct node
{
int num[10];
int position;
char path[50];
};
int a[10] = {0, 1, 1, 2, 6, 24, 120, 720, 5040, 40320};
bool flag[MAX];
int aim = 46233; //123456780 hash
int beginnum[10];
node n;
int beginposition;
int Move[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
char m[5] = {"rldu"};
int kt(int *x) // hash
{
int sum = 0;
for(int i = 1; i <= 9; i++)
{
int s = 0;
for(int j = i + 1; j <= 9; j++)
if(x[j] < x[i])
s++;
sum += s * a[10 - i];
}
return sum;
}
bool bfs()
{
n.position = beginposition;
int t = kt(n.num);
if(t == aim)
{
printf("
");
return true;
}
flag[t] = true;
strcpy(n.path, "\0");
queue<node> q;
q.push(n);
while(!q.empty())
{
node temp = q.front();
q.pop();
int x, y;
int tempx, tempy;
if(temp.position % 3 == 0)
{
x = temp.position / 3;
y = 3;
}
else
{
x = temp.position / 3 + 1;
y = temp.position % 3;
}
node p;
for(int j = 0; j < 4; j++)
{
tempx = x + Move[j][0];
tempy = y + Move[j][1];
if(tempx < 1 || tempx > 3 || tempy < 1 || tempy > 3)
continue;
for(int i = 0; i < 10; i++)
p.num[i] = temp.num[i];
int newposition = (tempx - 1) * 3 + tempy;
int jiaohuan = p.num[newposition];
p.num[newposition] = p.num[temp.position];
p.num[temp.position] = jiaohuan;
jiaohuan = kt(p.num);
if(flag[jiaohuan])
continue;
if(jiaohuan == aim)
{
strcpy(p.path, temp.path);
int len = strlen(temp.path);
p.path[len] = m[j];
p.path[len + 1] = '\0';
cout << p.path << endl;
return true;
}
flag[jiaohuan] = true;
p.position = newposition;
strcpy(p.path, temp.path);
int len = strlen(temp.path);
p.path[len] = m[j];
p.path[len + 1] = '\0';
q.push(p);
}
}
return false;
}
int main()
{
memset(flag, false, sizeof(flag));
char temp;
for(int i = 1; i <= 9; i++)
{
cin >> temp;
if(temp == 'x')
{
beginposition = i;
temp = '0';
}
n.num[i] = temp - '0';
}
bool mark = bfs();
if(!mark)
cout << "unsolvable" << endl;
system("pause");
return 0;
}