sicily 2011 Nine Digits

//新手赛广搜。。哎,当时头大只出了三道题,这道其实不难的。。 //想想自己以为模板是超级水题的,结果到场上竟然不敢下手。。泪流满面 //这题和魔板做法是一模一样,只不过搜索是预处理,先把所有 //状态都搜完,之后const输出而已 //四个数字转换,2*2块逆时针 //wengsht #include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; int fact[] = { 0,1,2,6,24,120,720,5040,40320,362880}; int z[] = { 1,10,100,1000,10000,100000,1000000,10000000,100000000 }; int s[9]; int nxt[4],key_nxt[4],key_now; const int mx = 362899; //状态数 9! = 362880 const int start = 123456789; bool _get[mx]; int path[mx]; //人家说这是。。康托压缩: int key( int p ) { int result = 0, temp[9]; for( int i = 8;i >= 0;i-- ) { temp[i] = p % 10; p /= 10; } for( int i = 0;i < 8;i++ ) { int cnt = 0; for( int j = i+1;j < 9;j++ ) if( temp[i] > temp[j] ) cnt++; result += fact[8-i] * cnt; } return result; } //123456789->253146789 int A( int num ) { int result = num % z[4]; result += num/z[5]%10*z[4]; result += num/z[8]*z[5]; result += num/z[6]%10*z[6]; result += num/z[4]%10*z[7]; result += num/z[7]%10*z[8]; return result; } //123456789->123469758 int B( int num ) { int result = num/z[5]*z[5]; result += num/z[1]%10; result += num/z[4]%10*z[1]; result += num/z[2]%10*z[2]; result += num%10*z[3]; result += num/z[3]%10*z[4]; return result; } //123456789->123586479 int C( int num ) { int result = num/z[6]*z[6] + num%10; result += num/z[2]%10*z[1]; result += num/z[5]%10*z[2]; result += num/z[3]%10*z[3]; result += num/z[1]%10*z[4]; result += num/z[4]%10*z[5]; return result; } //123456789->136425789 int D( int num ) { int result = num % z[3] + num/z[8]*z[8]; result += num/z[4]%10*z[3]; result += num/z[7]%10*z[4]; result += num/z[5]%10*z[5]; result += num/z[3]%10*z[6]; result += num/z[6]%10*z[7]; return result; } int main() { queue<int> q; q.push( start ); _get[0] = true; path[0] = 0; while( !q.empty() ) { int now = q.front(); q.pop(); nxt[0] = A( now ); nxt[1] = B( now ); nxt[2] = C( now ); nxt[3] = D( now ); key_now = key( now ); for( int i = 0;i < 4;i++ ) { key_nxt[i] = key( nxt[i] ); if( !_get[key_nxt[i]] ) { _get[key_nxt[i]] = true; q.push( nxt[i] ); path[ key_nxt[i] ] = path[key_now] + 1; } } } //搜完常数输出。。 int num,m; while( scanf("%d",&m) != EOF ) { num = m; for( int i = 0;i < 8;i++ ) { scanf("%d",&m); num = num * 10 + m; } printf("%d/n",path[key(num)]); } return 0; }

你可能感兴趣的:(sicily 2011 Nine Digits)