UVa1603 The Rotation Game (IDA*)

链接:http://acm.hust.edu.cn/vjudge/problem/36627分析:感觉这题前面的处理比较麻烦。首先把图中的位置从左到右从上到下编号,然后用一个二维数组记录8个方向上各个位置的编号,枚举最大深度maxd,乐观估计函数为至少需要移动次数,因为每次移动最多改变一个位置上的数字,所以中间8个位置除了出现次数最多的数字外的数字个数为x的话那么就至少要移动x次,枚举move8个方向再递归如果check为true则成功找到解返回,否则将a复位继续枚举,枚举完8个方向找不到解则失败返回false。
 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4
 5 /*
 6       00    01
 7       02    03
 8 04 05 06 07 08 09 10
 9       11    12
10 13 14 15 16 17 18 19
11       20    21
12       22    23
13 */
14
15 const int rev[8] = {5, 4, 7, 6, 1, 0, 3, 2};
16 const int center[8] = {6, 7, 8, 11, 12, 15, 16, 17};
17 int line[8][7] = {
18     {0, 2, 6, 11, 15, 20, 22},
19     {1, 3, 8, 12, 17, 21, 23},
20     {10, 9, 8, 7, 6, 5, 4},
21     {19, 18, 17, 16, 15, 14, 13},
22 };
23
24 int a[24];
25 char ans[1000];
26
27 int diff(int target) {
28     int cnt = 0;
29     for (int i = 0; i < 8; i++)
30         if (a[center[i]] != target) cnt++;
31     return cnt;
32 }
33
34 inline int h() {
35     return min(min(diff(1), diff(2)), diff(3));
36 }
37
38 bool check() {
39     for (int i = 0; i < 8; i++)
40         if (a[center[i]] != a[center[0]]) return false;
41     return true;
42 }
43
44 void move(int i) {
45     int tmp = a[line[i][0]];
46     for (int j = 0; j < 6; j++) a[line[i][j]] = a[line[i][j + 1]];
47     a[line[i][6]] = tmp;
48 }
49
50 bool dfs(int d, int maxd) {
51     if (check()) {
52         ans[d] = ‘\0‘;
53         printf("%s\n", ans);
54         return true;
55     }
56     if (maxd - d < h()) return false;
57     for (int i = 0; i < 8; i++) {
58         ans[d] = ‘A‘ + i;
59         move(i);
60         if (dfs(d + 1, maxd)) return true;
61         move(rev[i]);
62     }
63     return false;
64 }
65
66 int main() {
67     for (int i = 4; i < 8; i++)
68         for (int j = 0; j < 7; j++)
69             line[i][j] = line[rev[i]][6 - j];
70     while (scanf("%d", &a[0]) == 1 && a[0]) {
71         for (int i = 1; i < 24; i++) scanf("%d", &a[i]);
72         for (int i = 0; i < 24; i++) if (!a[i]) return 0;
73         if (check()) printf("No moves needed\n");
74         else for (int maxd = 1; ; maxd++)
75             if (dfs(0, maxd)) break;
76         printf("%d\n", a[6]);
77     }
78     return 0;
79 }
时间: 2024-08-10 14:57:51

UVa1603 The Rotation Game (IDA*)的相关文章

[poj2286]The Rotation Game (IDA*)

//第一次在新博客里发文章好紧张怎么办 //MD巨神早已在一个小时前做完了 The Rotation Game Time Limit: 15000MS Memory Limit: 150000K Total Submissions: 5950 Accepted: 1992 Description The rotation game uses a # shaped board, which can hold 24 pieces of square blocks (see Fig.1). The b

hdu 1667 The Rotation Game ( IDA* )

题目大意: 给你一个"井"子状的board,对称的由24个方块组成,每个方块上有123三个数字中的一个.给你初始状态,共有八种变换方式,求字典序最小的最短的的变换路径使得,board中间的八个方块上数字相同.(建议看下题目中的图就懂啦). IDA*搜索. 我是干脆用结构体保存搜索状态(当然这样很占空间了,可能也耗时间,不过这题15s/150M的时空限制我也是醉了).保存一个board temp,一个搜索路径path,搜索深度n,以及一个内置的估值函数h().h()返回的是8减这八个方块

UVa 1343 The Rotation Game(IDA*)

主要是设计乐观估计函数来减枝 假设中心区域有6个2,2个3,那肯定是消掉3最好,毕竟就两个. 那么理想情况下,旋转一次就能把一个3变成2,那么最少操作2次. 我们用h()来计算最少还要操作几次,其原理是假设中心区域都放1或2或3,返回至少操作的次数中最小的数 maxd是假设最多能操作的数; d是已经操作的数; 那么就可以得出乐观估计函数   h()+d>maxd 其含义为 : 若  至少还要操作次数  加上  已经操作的次数  大于  最多总共操作的次数就退出 . 其次就是节点的处理了,编个号数

POJ - 2286 - The Rotation Game (IDA*)

IDA*算法,即迭代加深的A*算法,实际上就是迭代加深+DFS+估价函数 题目传送:The Rotation Game AC代码: #include <map> #include <set> #include <list> #include <cmath> #include <deque> #include <queue> #include <stack> #include <bitset> #include

POJ 2286 The Rotation Game 迭代搜索深度 + A* == IDA*

感觉这种算法还是比较局限的吧,重复搜索是一个不好的地方,而且需要高效的估值函数来进行强剪枝,这点比较困难. 迭代搜索深度是一个比较炫酷的搜索方式,不过有点拿时间换空间的感觉. 首先迭代深度比较搓的写法是,首先设置一个阀值MaxH,初始为最小值. 当在搜索深度Depth <= MaxH时找到解则此时为最优解,否则MaxH++,继续深搜. 另外一种比较吊的写法是二分搜索深度,若搜到则减小阀值,否则增大阀值. 总之,迭代深度搜索就是通过改变深搜的深度来寻找最优解,这样做的好处是省掉了BFS中状态标记所

The Rotation Game (poj 2286 搜索IDA*)

Language: Default The Rotation Game Time Limit: 15000MS   Memory Limit: 150000K Total Submissions: 5573   Accepted: 1878 Description The rotation game uses a # shaped board, which can hold 24 pieces of square blocks (see Fig.1). The blocks are marked

UVa 1343 The Rotation Game (状态空间搜索 &amp;&amp; IDA*)

题意:有个#字型的棋盘,2行2列,一共24个格. 如图:每个格子是1或2或3,一共8个1,8个2,8个3. 有A~H一共8种合法操作,比如A代表把A这一列向上移动一个,最上面的格会补到最下面. 求:使中心8个格子数字一致的最少步骤,要输出具体的操作步骤及最终中心区域的数字.如果有多个解,输出字典序最小的操作步骤. 分析 : 还是状态空间的搜索,对象就是一个数字序列,判断中心位置是否一样,可以看出如果使用BFS,每一层还是爆炸,所以使用IDA*,关键还是模拟操作和h函数,这里的h函数是这样定义的,

POJ 2286 The Rotation Game(IDA*)

The Rotation Game Time Limit: 15000MS   Memory Limit: 150000K Total Submissions: 6396   Accepted: 2153 Description The rotation game uses a # shaped board, which can hold 24 pieces of square blocks (see Fig.1). The blocks are marked with symbols 1, 2

埃及分数&amp;&amp;The Rotation Game&amp;&amp;骑士精神——IDA*

IDA*:非常好用的搜索,可以解决很多深度浅,但是规模大的搜索问题. 估价函数设计思路:观察一步最多能向答案靠近多少. 埃及分数 题目大意: 给出一个分数,由分子a 和分母b 构成,现在要你分解成一系列互不相同的单位分数(形如:1/a,即分子为1),要求:分解成的单位分数数量越少越好,如果数量一样,最小的那个单位分数越大越好. 如: 19/45 = 1/3 + 1/12 + 1/180; 19/45 = 1/5 + 1/6 + 1/18; 以上两种分解方法都要3个单位分数,但下面一个的最小单位分