zoukankan      html  css  js  c++  java
  • poj1077

    题意:给出一个八数码问题,求解法,不可解则输出unsolvable。

    分析:可以用ida*算法,估价函数可以使用每个数码到其最终位置的最短距离之和。对于不可解的判断,我这里用迭代深度大于100时判定为不可解。

    还有一种更高级的无解判断方法。就是将八数码矩阵中的空格忽略,然后将8个数字排成一排,第二行接在第一行后面,第三行接在第二行后面,通过观察我们发现移动空格不会影响这个8个数字组成的数列中逆序数队的奇偶性,因此如果逆序数对的奇偶性与目标状态不同则一定无解。至于为什么奇偶性相同就一定有解,我就不知道为什么了,不过这个命题确实是正确的。

    可以将这种方法做适当修改并推广至15数码问题。

    #include <iostream>
    #include <stack>
    #include <cmath>
    using namespace std;
    
    const    int        maxn = 10;
    
    char    ans[100];
    int        tot, dir[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
    
    struct Node
    {
        char    map[maxn];
        int        g, move, xpos;
    }starts;
    
    void init()
    {
        for (int i = 0; i < 9; i++)
        {
            starts.map[i] = ' ';
            while (starts.map[i] == ' ')
                scanf("%c",&starts.map[i]);
            if (starts.map[i] == 'x')
            {
                starts.map[i] = 9;
                starts.xpos = i;
            } else
                starts.map[i] -= '0';
        }
    }
    
    int h(Node &a)
    {
        int        x1, x2, y1, y2, i, r = 0;
    
        for (i = 0; i < 9; i++)
        {
            x1 = i / 3;
            y1 = i % 3;
            x2 = (a.map[i] - 1) / 3;
            y2 = (a.map[i] - 1) % 3;
            r += abs(x1 - x2) + abs(y1 - y2);
        }
        return r;
    }
    
    Node getchild(int a, Node &currents)
    {
        int        x, y, pos, i;
        Node    r;
        
        x = currents.xpos / 3 + dir[a][0];
        y = currents.xpos % 3 + dir[a][1];
        r.xpos = -1;
        if (x < 0 || y < 0 || x > 2 || y > 2)
            return r;
        pos = x * 3 + y;
        r.xpos = pos;
        r.g = currents.g + 1;
        r.move = a;
        for (i = 0; i < 9; i++)
            r.map[i] = currents.map[i];
        r.map[pos] = 9;
        r.map[currents.xpos] = currents.map[pos];
        return r;
    }
    
    bool ida()
    {
        int        pathlimit, i, temp, next;
        bool    success = 0;
        Node    currents, child;
    
        next = h(starts)/2;
        stack<Node> stk;
        do
        {
            pathlimit = next;
            if (pathlimit > 100)
                return false;
            tot = 0;
            starts.g = 0;
            starts.move = -1;
            next = 200;
            stk.push(starts);
            do
            {
                currents = stk.top();
                ans[currents.g] = currents.move;
                stk.pop();
                temp = h(currents);
                if (temp == 0)
                {
                    tot = currents.g;
                    success = true;
                }
                else if (pathlimit >= currents.g + temp / 2)
                {
                    for (i = 0; i < 4; i++)
                    {
                        child = getchild(i, currents);
                        if (child.xpos != -1 && abs(child.move - currents.move) != 2)
                            stk.push(child);
                    }
                }else if (next > currents.g + temp / 2)
                    next = currents.g + temp / 2;
            }while (!success && !stk.empty());
        }while (!success);
        return true;
    }
    
    void print()
    {
        int        i;
    
        for (i = 1; i <= tot; i++)
            switch(ans[i])
            {
                case 0: printf("u"); break;
                case 1: printf("r"); break;
                case 2: printf("d"); break;
                case 3: printf("l"); break;
            }
        printf("
    ");
    }
    
    int main()
    {
        //freopen("t.txt", "r", stdin);
        init();
        if (ida())
            print();
        else
            printf("unsolvable
    ");
        return 0;
    }
    View Code
  • 相关阅读:
    将HTTP请求对象转成curl命令行
    图片爬虫实践
    [CF1499E] Chaotic Merge
    [ICPC2020南京I] Interested in Skiing
    [ICPC2018西安J] Philosophical … Balance
    [ICPC2018西安L] Eventual … Journey
    [ICPC2018西安I] Misunderstood … Missing
    [ICPC2018西安D] Deja vu of … Go Players
    [ICPC2018西安F] Interstellar … Fantasy
    [ICPC2020南京L] Let's Play Curling
  • 原文地址:https://www.cnblogs.com/rainydays/p/3201519.html
Copyright © 2011-2022 走看看