uva 11198

来源:互联网 发布:输入网络密码来连接到 编辑:程序博客网 时间:2024/05/18 02:11

题意:给你一个排列,让你排序成绝对值从小到达的最小步数,交换条件是,两位是异号,并且和为素数,看了别人的哈希,就用哈希保存所有的情况

#include <iostream>#include <cstring>#include <cstdio>#include <cmath>using namespace std;const int HashSize = 1000003 ;typedef int State[8];State start ;State que[50000];int head[HashSize],next[HashSize],step[50000],ans;int prim[16]={0,0,1,1,0,1,0,1,0,0,0,1,0,1,0,0}; inline void init_lookup_table(){ans = -1 ;step[0] = 0 ;memset(head,0,sizeof(head));}inline int hash(State &s){int v = 0 ;for (int i = 0 ; i < 8 ; i++)v = v*10 +abs(s[i]);return( v & 0x7FFFFFFF ) % HashSize;}inline bool try_to_insert(int s){int h = hash(que[s]);int u = head[h];while ( u ){if ( memcmp(que[u],que[s],sizeof(que[s])) == 0 )return false ;u = next[u];}next[s] = head[h];head[h] = s ;return true;}bool is_ok(State &s){for (int i = 0 ; i < 7 ; i++)if ( abs(s[i])>abs(s[i+1]))return false ;return true;}void goto_dance(State &s,int u,int v,int dir){if (dir == 1){if (u == v-1)return ;if (u == v+1){int tmp = s[u];s[u] = s[v];s[v] = tmp;}int t=s[u];if (u > v){for (int i = u ; i > v ; i--)s[i] = s[i-1];s[v] = t;}else {for (int i = u ; i < v-1 ; i++)s[i] = s[i+1];s[v-1] = t ;}}else {if (u == v+1)return ;if (u == v-1){int tmp = s[u];s[u] = s[v];s[v] = tmp;}int t = s[u];if (u > v){for (int i = u ; i >v+1 ;i--)s[i] = s[i-1];s[v+1] = t ;}else {for (int i = u ; i < v ; i++)s[i] = s[i+1];s[v] = t ;}}}void bfs(){init_lookup_table();int front=0,rear=1;memcpy(que[0],start,sizeof(start));try_to_insert(0);while (front < rear){State &s = que[front];if (is_ok(s)){ans = step[front];return ;}for (int i = 0 ; i < 8 ; i++){for (int j = 0 ; j < 8 ; j++)if ( i != j && ((s[i] < 0 && s[j] >0) ||( s[i] > 0 && s[j] < 0 ))){int sum = abs(s[i]) + abs(s[j]) ;if ( !prim[sum])continue;for (int k = 1 ; k <= 2 ; k++){State &t = que[rear];memcpy(t,s,sizeof(s));goto_dance(t,i,j,k);if (try_to_insert(rear)){step[rear] = step[front] + 1;rear++;}}}}++front;}}int main(){int cas = 1;while (scanf("%d",&start[0]) != EOF && start[0]){for (int i = 1 ; i < 8 ; i++)scanf("%d",&start[i]);bfs();printf("Case %d: %d\n",cas++,ans);}return 0;}