5997 Problem C【寬搜入門】8數碼難題
阿新 • • 發佈:2018-12-04
問題 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; }