HDU

来源:互联网 发布:js多选日期插件 编辑:程序博客网 时间:2024/06/02 05:05

典型的IDA*题目
估值函数:从当前状态移动到目标状态所需的最小步数(我们可以通过曼哈顿距离进行估值),用于剪枝
迭代:此处我们不再使深度每次加1,而是在搜索过程当中,记录大于len(len表示此次搜索的限制深度)的所有值中的最小值,作为下次迭代的限制深度

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <vector>#include <cmath>#include <stack>using namespace std;int factor[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};int dx[] = {1, 0, 0, -1};int dy[] = {0, -1, 1, 0};int target, posx, posy, len, nextlen;bool vis[363000];int a[3][3], b[3][3], px[9], py[9];stack<int> s;int cantor(int t[][3]){    int x[9];    for (int i = 0; i < 9; i++)        x[i] = t[i / 3][i % 3];    int ans = 0;    for (int i = 0; i < 9; i++)    {        int cnt = 0;        for (int j = i + 1; j < 9; j++)            if (x[i] > x[j])                cnt++;        ans += cnt * factor[9 - i - 1];    }    return ans;}int geth(int t[][3]){    int ans = 0;    for (int i = 0; i < 3; i++)        for (int j = 0; j < 3; j++)        {            if (!t[i][j]) continue;            ans += abs(i - px[t[i][j]]) + abs(j - py[t[i][j]] % 3);        }    return ans;}bool ID_Astar(int state, int x, int y, int step){    if (state == target)        return true;    for (int i = 0; i <= 3; i++)    {        int cx = x + dx[i];        int cy = y + dy[i];        if (0 <= cx && cx <= 2 && 0 <= cy && cy <= 2)        {            swap(a[x][y], a[cx][cy]);            int f = step + 1 + geth(a);            if (f > len)                nextlen = min(f, nextlen);            if (f <= len)            {                int nextstate = cantor(a);                if (!vis[nextstate])                {                    vis[nextstate] = true;                    s.push(i);                    if (ID_Astar(nextstate, cx, cy, step + 1))                        return true;                    s.pop();                    vis[nextstate] = false;                }            }            swap(a[x][y], a[cx][cy]);        }    }    return false;}int main(){    int T, k = 0;    cin >> T;    while (T--)    {        char ch;        for (int i = 0; i < 3; i++)            for (int j = 0; j < 3; j++)            {                cin >> ch;                if (ch == 'X')                    a[i][j] = 0, posx = i, posy = j;                else                    a[i][j] = ch - '0';            }        for (int i = 0; i < 3; i++)            for (int j = 0; j < 3; j++)            {                cin >> ch;                if (ch == 'X')                    b[i][j] = 0;                else                {                    b[i][j] = ch - '0';                    px[b[i][j]] = i;                    py[b[i][j]] = j;                }            }        target = cantor(b);        int start = cantor(a);        cout << "Case " << ++k << ": ";        memset(vis, 0, sizeof(vis));        vis[start] = true;        len = 0;        for (;;)        {            nextlen = 0x3f3f3f3f;            while (!s.empty()) s.pop();            if (ID_Astar(start, posx, posy, 0)) break;            if (nextlen == 0x3f3f3f3f)                nextlen = len + 1;            len = nextlen;        }        char cc[] = {'d', 'l', 'r', 'u'};        vector<int> ans;        while (!s.empty())            ans.push_back(s.top()), s.pop();        cout << ans.size() << endl;        for (int i = ans.size() - 1; i >= 0; i--)            cout << cc[ans[i]];        cout << endl;    }    return 0;}