紫书搜索 例题7-12 UVA - 1343 The Rotation Game IDA*迭代加深搜索

题目链接:

https://vjudge.net/problem/UVA-1343

题意:

数字1,2,3都有八个,求出最少的旋转次数使得图形中间八个数相同。
旋转规则:对于每一长行或每一长列,每次旋转就是将数据向头的位置移动一位,头上的数放置到尾部。若次数相同,则找出字典序最小旋转次序。
输入是从上到下,从左向右,注意方向

题解:

代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 #define MS(a) memset(a,0,sizeof(a))
 5 #define MP make_pair
 6 #define PB push_back
 7 const int INF = 0x3f3f3f3f;
 8 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
 9 inline ll read(){
10     ll x=0,f=1;char ch=getchar();
11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
12     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
13     return x*f;
14 }
15 //////////////////////////////////////////////////////////////////////////
16 const int maxn = 1e5+10;
17 
18 int maxd,ok,a[50];
19 char ans[maxn];
20 int line[8][7] = {
21     {0,2,6,11,15,20,22},
22     {1,3,8,12,17,21,23},
23     {10,9,8,7,6,5,4},
24     {19,18,17,16,15,14,13}
25 };
26 
27 int rev[8] = {5,4,7,6,1,0,3,2}; // 通过A,B,C,D,反推其他方向。指向反向,用来还原现场。  
28 int final[8] = {6,7,8,11,12,15,16,17}; // 最后答案要求的点  
29 
30 void init(){ // 反推方向
31     for(int i=4; i<8; i++)
32         for(int j=0; j<=6; j++)
33             line[i][j] = line[rev[i]][6-j];
34 }
35 
36 bool is_final(){
37     int k = a[final[0]];
38     for(int i=1; i<8; i++)
39         if(a[final[i]]!=k) return false;
40     return true;
41 }
42 
43 void move(int k){
44     int tmp = a[line[k][0]];
45     for(int i=1; i<7; i++)
46         a[line[k][i-1]] = a[line[k][i]];
47     a[line[k][6]] = tmp;
48 }
49 
50 int diff(int x){
51     int cnt = 0;
52     for(int i=0; i<8; i++)
53         if(x != a[final[i]])
54             cnt++;
55     return cnt;
56 }
57 
58 int h(){ //估值函数  
59     return min(min(diff(1),diff(2)),diff(3));
60 }
61 
62 void dfs(int cur){
63     if(is_final()){
64         ans[cur] = '\0';
65         cout << ans << endl;
66         ok = 1;
67         return ;
68     }
69 
70     if(cur+h() > maxd) return ; //剪枝
71     for(int i=0; i<8; i++){
72         ans[cur] = 'A'+i;
73         move(i);
74         dfs(cur+1);
75         if(ok) return ;
76         move(rev[i]); // 还原现场  
77     }
78 }
79 
80 int main(){
81     init();
82     while(scanf("%d",&a[0]) && a[0]){
83         for(int i=1; i<24; i++) a[i]=read();
84         ok = 0;
85         if(is_final())
86             puts("No moves needed");
87         else{
88             for(maxd=1; ; maxd++){
89                 dfs(0);
90                 if(ok) break;
91             }
92         }
93         cout << a[6] << endl; // 最终的颜色 
94     }
95 
96     return 0;
97 }

 

posted @ 2017-03-12 19:20  _yxg123  阅读(200)  评论(0编辑  收藏  举报