uva 1343 IDA*

来源:互联网 发布:java电商项目简历 编辑:程序博客网 时间:2024/06/05 06:50

转载别人的:

从小到大依次枚举深度上限maxd。对于每一个深度上限,进行dfs,当递归到maxd时,就要判断是否找到了解,如果找到了,就记录或者输出解。不论是否找到了解,都要开始返回,对于找到了解的情况,可以在函数出口处连续返回。
那么如何及时的返回呢?答案就是寻找“估价函数”并“剪枝”。对于本题,可以发现,每次移动最多只能让目标数字多1个,因此可以将min{diff(1),diff(2),diff(3)}作为估价函数。其中diff(i)是目标格子中不等于数字i的个数。这样以来,如果发现最少要移动的步数h()仍然大于maxd-cur,就需要进行剪枝。

#include <bits/stdc++.h>using namespace std;int line[8][7] ={{0, 2, 6, 11, 15, 20, 22},{1, 3, 8, 12, 17, 21, 23},{10, 9, 8, 7, 6, 5, 4},{19, 18, 17, 16, 15, 14, 13},};const int rev[8] = {5, 4, 7, 6, 1, 0, 3, 2};const int center[8] = {6, 7, 8, 11, 12, 15, 16, 17};int a[24];char ans[1000];bool is_final(){for (int i = 0; i < 8; i++)if (a[center[i]] != a[center[0]]) return false;return true;}int diff(int target){int ans = 0;for (int i = 0; i < 8; i++)if (a[center[i]] != target) ans++;return ans;}inline int h(){return min(min(diff(1), diff(2)), diff(3));}inline void move(int i){int tmp = a[line[i][0]];for (int j = 0; j < 6; j++)a[line[i][j]] = a[line[i][j + 1]];a[line[i][6]] = tmp;}bool dfs(int d, int maxd){if (is_final()){ans[d] = '\0';cout << ans << endl;return true;}if (d + h() > maxd) return false;for (int i = 0; i < 8; i++){ans[d] = 'A' + i;move(i);if (dfs(d + 1, maxd)) return true;move(rev[i]);// 否则回复原样}return false;}int main(int argc, char const *argv[]){for (int i = 4; i < 8; i++)for (int j = 0; j < 7; j++)line[i][j] = line[rev[i]][6 - j];//初始化E-Gwhile (cin >> a[0] && a[0]){for (int i = 1; i < 24; i++)cin >> a[i];for (int i = 0; i < 24; i++) if (!a[i]) return 0;if (is_final())cout << "No moves needed" << endl;else for (int maxd = 1;; maxd++)if (dfs(0, maxd)) break;cout << a[6] << endl;}return 0;}


0 0