• POJ1184-------操作分离的BFS


    题目地址:http://poj.org/problem?id=1184

    题目意思:

    给你两个6位数,一个是起始值,一个最终值

    初始光标在最左边

    你可以左移或者右移光变

    在光标处+1或者-1

    在光标处和最左边或者和最右边交换

    问你最少要多少就可以由初始值转换到最终值

    解题思路:

    操作分离是解决这题的核心思想

    就是说我们反正要进行一些转换的,不如先全部转换了算了

    通过一个BFS预处理将所有可能转换的全部转换,光标所有可能的位置全部求出来

    然后在每次要求的时候,对每种状态上的光标进行加减操作

    求出最少的步骤

    另外这题的测试数据有问题,其实左移也是需要的

    比如000159 和 000519,正确答案是8,如果不考虑左移就是12

    再就是我们可以将光标的访问情况压缩到10种,具体的在我代码中有解释

    下面上代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<string>
    #include<map>
    #include<queue>
    using namespace std;
    
    struct node
    {
        int state;
        int pos;
        int num[6];
        int step;
        int fangwen[6];
    };
    
    int vis_state[10][6] =
    {
        1,0,0,0,0,0,  /*访问状态0: 初始状态(pos=0)*/
        1,1,0,0,0,0,  /*访问状态1: 状态0通过右移操作得到(pos=1),或者状态1通过swap0操作得到(pos=1)*/
        1,1,1,0,0,0,  /*访问状态2: 状态1通过右移操作得到(pos=2),或者状态2通过swap0操作得到(pos=2)*/
        1,1,1,1,0,0,  /*访问状态3: 状态2通过右移操作得到(pos=3),或者状态3通过swap0操作得到(pos=3)*/
        1,1,1,1,1,0,  /*访问状态4: 状态3通过右移操作得到(pos=4),或者状态4通过swap0操作得到(pos=4)*/
        1,0,0,0,0,1,  /*访问状态5: 状态0通过swap1操作得到(pos=0),或者状态5通过swap0操作得到(pos=0)*/
        1,1,0,0,0,1,  /*访问状态6: 状态1通过swap1操作得到(pos=1),或者状态5通过右移操作得到(pos=1),或者状态6通过swap0操作得到(pos=1)*/
        1,1,1,0,0,1,  /*访问状态7: 状态2通过swap1操作得到(pos=2),或者状态6通过右移操作得到(pos=2),或者状态7通过swap0操作得到(pos=2)*/
        1,1,1,1,0,1,  /*访问状态8: 状态3通过swap1操作得到(pos=3),或者状态7通过右移操作得到(pos=3),或者状态8通过swap0操作得到(pos=3)*/
        1,1,1,1,1,1   /*访问状态9: 状态4通过swap1操作得到(pos=4),或者状态8通过右移操作得到(pos=4),或者状态9通过右移操作得到(pos=5),
                                   或者状态4通过右移操作得到(pos=5),或者状态9通过swap0操作得到,或者状态9通过swap1操作得到*/
    };
    
    int state[10000][8]; //对应的是所有情况,第二维记录相应信息
    
    int idx;
    int co;
    
    bool vis[6][6][6][6][6][6][6][10];  //前6个是数字,为什么只到6,是因为这个是做排列用的
                                        //第7个是光标所在位置用的,第8个事state
    
    void put_to_vis(node a)
    {
        vis[a.num[0]][a.num[1]][a.num[2]][a.num[3]][a.num[4]][a.num[5]][a.pos][a.state] = true;
    }
    
    bool check(node a)
    {
        return vis[a.num[0]][a.num[1]][a.num[2]][a.num[3]][a.num[4]][a.num[5]][a.pos][a.state];
    }
    
    int find_state(node a)
    {
        if(a.fangwen[5]==0)
        {
            int cnt = 0;
            for(int i=1;i<5;i++)
                if(a.fangwen[i])
                    cnt++;
            return cnt;
        }
        else
        {
            int cnt = 0;
            for(int i=1;i<5;i++)
                if(a.fangwen[i])
                    cnt++;
            return cnt+5;
        }
    }
    
    
    
    void bfs()
    {
        queue<node> Q;
        node a,b;
        idx=0;
        co=0;
        for(int i=0;i<6;i++)
        {
            a.num[i] = i;
            a.fangwen[i] = 0;
        }
    
        a.pos = a.state = a.step = 0;
        a.fangwen[0] = 1;
        Q.push(a);
        put_to_vis(a);
    
        //printf("a step %d
    ",a.step);
        int co2=0;
    
        while(!Q.empty())
        {
            co++;
            a = Q.front();
            Q.pop();
    
            for(int i=0;i<6;i++)
                state[idx][i] = a.num[i];
            state[idx][6] = a.state;
            state[idx][7] = a.step;
            idx++;
    
            if(a.pos>0) //左移或者左交换操作
            {
                //左移操作
                b=a;
                b.step = a.step+1;
                b.pos--;
                if(!check(b))
                {
                    put_to_vis(b);
                    Q.push(b);
                }
    
                //左交换
                b = a;
                b.step = a.step+1;
                swap(b.num[0],b.num[b.pos]);
                if(!check(b))
                {
                    put_to_vis(b);
                    Q.push(b);
                }
            }
    
            if(a.pos<5) //右移和右交换操作
            {
                //右移
                b=a;
                b.step = a.step+1;
                b.pos++;
                b.fangwen[b.pos] = 1;
                b.state = find_state(b);
                if(!check(b))
                {
                    put_to_vis(b);
                    Q.push(b);
                }
    
                //右交换
                b = a ;
                b.step = a.step+1;
                swap(b.num[5],b.num[b.pos]);
                b.fangwen[5] = 1;
                b.state = find_state(b);
                if(!check(b))
                {
                    put_to_vis(b);
                    Q.push(b);
                }
            }
        }
    }
    
    int main()
    {
        memset(vis,false,sizeof(vis));
        bfs();
        char st[10];
        char ed[10];
        int _st[6];
        int _ed[6];
        while(scanf("%s%s",st,ed) != EOF)
        {
            for(int i=0;i<6;i++)
            {
                _st[i] = st[i]-'0';
                _ed[i] = ed[i]-'0';
            }
    
    
            int ans = 99999999;
    
            for(int i=0;i<idx;i++)
            {
                int tmp = state[i][7];//初始化为进行了交换后的步数
                bool flag = true;
                int j;
                for(j=0;j<6;j++)
                {
                    if(!vis_state[state[i][6]][j] && (_st[state[i][j]]!=_ed[j])  )
                    {
                        flag = false;
                        break;
                    }
                    else
                    {
                        tmp += abs( _st[state[i][j]] - _ed[j]); //再加上每位进行加减 操作的步数
                    }
                }
    
                if(flag)
                    ans = min(ans,tmp);
    
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    
    
    
    
    
    
    
    
    
    
    


  • 相关阅读:
    Docker Harbor安装和使用
    k8s部署使用Jenkins
    K8S之Deployment
    K8S之StatefulSet
    Gitlab数据迁移和版本升级
    centos7 编译安装git工具
    K8S之secret
    SonarQube的安装和使用
    Jenkins常用构建工具
    el-upload上传/预览时dialog宽自适应
  • 原文地址:https://www.cnblogs.com/snake-hand/p/3177793.html
Copyright © 2020-2023  润新知