1. 程式人生 > >5997 Problem C【寬搜入門】8數碼難題

5997 Problem C【寬搜入門】8數碼難題

問題 C: 【寬搜入門】8數碼難題

時間限制: 20 Sec  記憶體限制: 128 MB
提交: 85  解決: 26
[提交][狀態][討論版][命題人:外部匯入]

題目描述

初始狀態的步數就算1,哈哈

輸入:第一個3*3的矩陣是原始狀態,第二個3*3的矩陣是目標狀態。 
輸出:移動所用最少的步數 

Input

2 8 3 
1 6 4 
7 0 5 
1 2 3 
8 0 4 
7 6 5 

Output

6

#include<iostream>
#include<cstdio>
#include<queue>
#include<map>
#include<algorithm>
using namespace std;
int start, termination, pos;

struct node {
	int num, step, pos;//狀態、步數、0的下標
	node(int n, int s, int p) {
		num = n, step = s, pos = p;
	}
};

int oper(char str[], int p, int flag, bool operate) {
	if (flag == 0 && operate || flag == 1 && !operate) {//up
		if (p < 3)return -1;
		swap(str[p], str[p - 3]);
		return p - 3;
	}
	else if (flag == 1 && operate || flag == 0 && !operate) {//down
		if (p >= 6) return -1;
		swap(str[p], str[p + 3]);
		return p + 3;
	}
	else if (flag == 2 && operate || flag == 3 && !operate){//left
		if (p % 3 == 0)return -1;
		swap(str[p], str[p - 1]);
		return p - 1;
	}
	else {//right
		if (p % 3 == 2)return -1;
		swap(str[p], str[p + 1]);
		return p + 1;
	}
}

queue<node> q;
map<int, bool> mp;
void BFS() {
	char temp[10];
	int temp1;
	node s(start, 1, pos);
	q.push(s);
	mp[start] = true;
	while (!q.empty()) {
		s = q.front();
		q.pop();
		if (s.num == termination) {
			cout << s.step << endl;
			return;
		}
		sprintf(temp, "%d", s.num);
		if (s.num < 100000000) {//注意第一個數字為0時轉換
			for (int i = 8; i > 0; i--) {
				temp[i] = temp[i - 1];
			}
			temp[0] = '0';
		}
		for (int i = 0; i < 4; i++) {
			int d = oper(temp, s.pos, i, true);
			if (d == -1)continue;
			sscanf(temp, "%d", &temp1);
			if (mp.count(temp1) == 0) {
				node r(temp1, s.step + 1, d);
				q.push(r);
				mp[temp1] = true;
			}
			oper(temp, d, i, false);
		}
	}
}

int main() {
	int n;
	while (cin >> n) {
		if (n == 0) pos = 0;
		start = n, termination = 0;
		for (int i = 1; i < 9; i++) {
			cin >> n;
			start = start * 10 + n;
			if (n == 0) pos = i;
		}
		for (int i = 0; i < 9; i++) {
			cin >> n;
			termination = termination * 10 + n;
		}
		BFS();
	}

	return 0;
}