• hdu3567 八数码(搜索)--预处理


    题意:为你两个状态,求a到b 的最小路径,要求字典序最小。

    思路:

    最开始想的是目标状态是变化的,所以打表应该不行,然后直接上A*,但是TLE了- -(瞬间无语)

    然后看了下别人的思路,预处理出9个状态(好机智),然后打表。

    因为x所在的位置只有9中,我们可以根据x的位置打表,而且不同的串可以等效替代

    例: 564178x23 7568x4123

    --> 123456x78 5126x3478

    而且题目保证一定会有解。 所以bfs+打表,至于双向bfs,写了发现一直cuo,后来发现在反向搜索时很难保证最小字典序,如果有两条路走到同一个节点,你就要比较它们长短,一样则比大小

    问题:

    ①没考虑到a = b时的情况(果然很水)

    ②a = b时后面还有空行- -,也是醉的不行

    ③考虑不够全面,一开始就把打表这个排除了,


    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <queue>
    #include <algorithm>
    typedef long long ll;
    using namespace std;
    
    const int maxn = 3700000;
    int fac[] = {1,1,2,6,24,120,720,5040,40320,362880};
    int vis[10][maxn];
    
    struct node
    {
        int matrix[10];
        int position;
        int state;
    };
    
    int cantor(int s[])
    {
        int sum = 0;
        for(int i = 0; i < 9; i ++)
        {
            int num = 0;
            for(int j = i+1; j < 9; j++)
                if(s[j] < s[i])  num++;
            sum += (num*fac[9-i-1]);
        }
        return sum + 1;
    }
    
    
    struct node2
    {
        int pre;
        char ch;
    } pre[10][maxn];
    
    char dire[5]="dlru";
    int dir[4] = {3,-1,1,-3};
    node cur;
    
    
    void bfs(int t)
    {
        queue<node>q;
        vis[t][cur.state] = 1;
        int tnum = 1;
        pre[t][1].pre = -1;
        q.push(cur);
        while(!q.empty())
        {
            cur = q.front();
            q.pop();
            for(int i = 0; i < 4; i++)
            {
                if(i==3&&cur.position<3)continue;
                if(i==2&&cur.position%3==2)continue;
                if(i==0&&cur.position>5)continue;
                if(i==1&&cur.position%3==0)continue;
                node tmp = cur;
                tmp.position = cur.position + dir[i];
                tmp.matrix[cur.position] = tmp.matrix[tmp.position];
                tmp.matrix[tmp.position] = 0;
                tmp.state = cantor(tmp.matrix);
                if(!vis[t][tmp.state])
                {
                    vis[t][tmp.state] = ++tnum;
                    pre[t][tnum].ch = dire[i];
                    pre[t][tnum].pre = vis[t][cur.state];
                    q.push(tmp);
                }
            }
        }
        return ;
    }
    int all;
    void pri(int t,int k)
    {
        if(pre[t][k].pre == -1)
        {
            printf("%d
    ",all);
            return;
        }
        all++;
        pri(t,pre[t][k].pre);
        printf("%c",pre[t][k].ch);
    }
    
    void get_(int k)
    {
        int tot = 0;
        for(int i = 0; i < 9; i++)
        {
            if(i == k)
                continue;
            else
                cur.matrix[i] = ++tot;
        }
        cur.matrix[k] = 0;
        cur.position = k;
        cur.state = cantor(cur.matrix);
    }
    
    int num[10];
    int main()
    {
        get_(0);
        bfs(0);
        get_(1);
        bfs(1);
        get_(2);
        bfs(2);
        get_(3);
        bfs(3);
        get_(4);
        bfs(4);
        get_(5);
        bfs(5);
        get_(6);
        bfs(6);
        get_(7);
        bfs(7);
        get_(8);
        bfs(8);
    
        node from,to;
        int cas = 1;
        int n;
        scanf("%d",&n);
        char a[10];
        char b[10];
        while(n--)
        {
            scanf("%s",a);
            scanf("%s",b);
            printf("Case %d: ",cas++);
            int posi;
            for(int i = 0,j = 0; i < strlen(a); i++)
            {
                if(a[i] == 'x' || a[i] == 'X')
                    posi = i;
    
                else
                    num[a[i]-'0'] = j++;
            }
    
            for(int i = 0; i < strlen(b); i++)
            {
                if(b[i] == 'x' || b[i] == 'X')
                {
                    from.position = i;
                    from.matrix[i] = 0;
                }
                else
                {
                    from.matrix[i] = num[b[i]-'0']+1;
                }
            }
            from.state = cantor(from.matrix);
            if(!strcmp(a,b))
            {
                printf("0
    ");
                printf("
    ");
                continue;
            }
    //        for(int i = 0; i < 9; i++)
    //            printf("%d ",from.matrix[i]);
    //
    //        printf("%d",from.state);
            all = 0;
            pri(posi,vis[posi][from.state]);
            printf("
    ");
        }
        return 0;
    }
    

      




  • 相关阅读:
    一个程序员的职业规划
    基于Andoird 4.2.2的Account Manager源代码分析学习:创建选定类型的系统帐号
    [置顶] C++学习书单
    js快速分享代码
    The declared package does not match the expected package
    IBM Rational Appscan Part 1
    IBM Rational Appscan: Part 2 ---reference
    阅读redis源代码的一些体会
    18 Command Line Tools to Monitor Linux Performance
    代码规范
  • 原文地址:https://www.cnblogs.com/Przz/p/5409707.html
Copyright © 2020-2023  润新知