題目連接 : http://acm.xidian.edu.cn/land/problem/detail?problem_id=1006node
Description算法
wm最近喜歡上一種無聊的轉盤解鎖遊戲,他天天都會爲這遊戲消磨上三個小時的時間。這遊戲由三個正六邊形拼成,拼成後一共有13個點,其中有4個黑點和9個白點,以下圖。每一步能夠順時針或逆時針轉動三個六邊形的任意一個60度,轉動時六邊形的頂點也會相應轉動,而這遊戲的目的是把四個黑點都轉到中間(圖中最後一個狀態)。這是一個很簡單的遊戲,想達到遊戲目的並不難,但wm以爲這樣沒挑戰性,他決定對於任意一個初始狀態,用最少的步數去玩這個遊戲。app
1 #include "stdio.h" 2 3 // change status 4 int turn(int status,int op) 5 { 6 static int ops[6][6]={ 7 {0, 2, 5, 8, 6, 3}, {0, 3, 6, 8, 5, 2}, 8 {1, 3, 6, 9, 7, 4}, {1, 4, 7, 9, 6, 3}, 9 {6, 8, 10, 12, 11, 9}, {6, 9, 11, 12, 10, 8}}; 10 11 12 //// trans status to node status 13 int node[13]={} ; 14 int tmp , i ; 15 for(i = 0 ; status ; status>>=1) { 16 node[i++] = status & 1 ; 17 } 18 //// do operation , and get res 19 20 for(tmp = node[ops[op][i=0]]; i < 5 ; i++){ 21 node[ops[op][i]] = node[ops[op][i+1]] ; 22 } 23 node[ops[op][5]] = tmp ; 24 for(i = 0 ; i < 13 ; i++){ 25 status |= node[i]<<i ; 26 } 27 return status ; 28 } 29 30 31 32 int main() 33 { 34 ///// the max number status is 1111000000000 , is 0x1E00 35 int status[int(0x1E01)] = {} ; 36 int res[int(0x1E01)] = {} ; 37 ///// final status is 0001101001000 , is 0x348 38 res[int(0x348)] = 0 ; 39 status[0] = 0x348 ; 40 int s_sum = 1 ; 41 int i , j ; 42 char str[13] = {}; 43 ///// Cal the res array 44 for(i = 0 ; i < s_sum ; i++){ 45 for(j = 0 ; j < 6 ; j++){ 46 int next_s = turn(status[i],j); 47 if(res[next_s]<=0){ 48 res[next_s] = res[status[i]] + 1 ; 49 status[s_sum++] = next_s ; 50 } 51 } 52 } 53 ///output answer 54 for(;scanf("%s",str)!=EOF;printf("%d\n",res[j])){ 55 for(i = 0 , j = 0 ; i < 13 ; i++){ 56 j |= (str[i]-'0')<<i ; 57 } 58 } 59 return 0; 60 }