hdu 1043 反向bfs標號+dfs查詢+stl+狀態壓縮
阿新 • • 發佈:2018-12-31
因為9!=362880,所以我們可以通過寬搜從目標找到所有可達的情況,然後利用stl中的mp標記出,最後可以log(n)的查詢,屬於先打表後查詢,用十進位制數標記狀態
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <map> #include <queue> #define MAX 13 #define N 700007 using namespace std; typedef long long LL; map<LL,int> mark; LL pos[MAX]; LL state; LL goal; int num[MAX]; bool flag; void init ( ) { pos[0] = 1; for ( int i = 1 ; i <= 10 ; i++ ) pos[i] = pos[i-1]*10; goal = 0; for ( int i = 0 ; i < 8 ; i++ ) goal += pos[i]*(i+1); } struct Node { int x,t,pre,id; char op; LL s; }node[N]; int id = 1; void set ( int a , int b , int c , LL d , char op ) { node[id].x = a; node[id].t = b; node[id].pre = c; node[id].s = d; node[id].op = op; node[id].id = id; } bool bfs ( ) { queue<Node> q; mark.clear(); set ( 8 , 0 , -1 , goal , 0 ); mark[goal] = 1; q.push ( node[id++] ); while ( !q.empty( ) ) { Node old = q.front(); // cout << old.s << endl; int x = old.x; for ( int i = 0 ; i < 9 ; i++ ) num[i] = (old.s/pos[i])%10; q.pop ( ); if ( x-3 >= 0 ) { LL s = old.s + num[x-3]*pos[x] + num[x]*pos[x-3] - num[x-3]*pos[x-3] - num[x]*pos[x]; if ( !mark[s] ) { mark[s] = id; set ( x-3 , old.t+1 , old.id , s , 'd' ); q.push ( node[id++] ); } } if ( x+3 < 9 ) { LL s = old.s + num[x+3]*pos[x] + num[x]*pos[x+3] - num[x+3]*pos[x+3] - num[x]*pos[x]; if ( !mark[s] ) { mark[s] = id; set ( x+3 , old.t+1 , old.id , s , 'u' ); q.push ( node[id++] ); } } if ( (x-1)/3 == x/3 ) { LL s = old.s + num[x-1]*pos[x] + num[x]*pos[x-1] - num[x-1]*pos[x-1] - num[x]*pos[x]; if ( !mark[s] ) { mark[s] = id; set ( x-1 , old.t+1 , old.id , s , 'r' ); q.push ( node[id++] ); } } if ( (x+1)/3 == x/3 ) { LL s = old.s + num[x+1]*pos[x] + num[x]*pos[x+1] - num[x+1]*pos[x+1] - num[x]*pos[x]; if ( !mark[s] ) { mark[s] = id; set ( x+1 , old.t+1 , old.id , s , 'l' ); q.push ( node[id++] ); } } } } void dfs ( int id ) { if ( node[id].pre == -1 ) return; printf ( "%c" , node[id].op ); dfs ( node[id].pre ); } int main ( ) { // cout << 9*8*7*6*5*4*3*2*1<<endl; init ( ); bfs( ); //cout << "dasdasdasdas" << endl; char str[5]; while ( ~scanf ( "%s" , str ) ) { if ( str[0] != 'x' ) state = str[0] -48; else state = 0; for ( int i = 1 ; i < 9 ; i++ ) { scanf ( "%s" , str ); if ( str[0]!= 'x' ) state += ( str[0] - 48 )*pos[i]; } // cout << goal << endl; // cout << state << endl; //int id = mark[state]; //dfs ( id ) int id = mark[state]; if ( state == goal ) puts ( "" ); else if ( id ) { dfs ( id ); puts ( "" ); } else puts ( "unsolvable" ); } }