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; }