zoukankan      html  css  js  c++  java
  • poj1077(康托展开+bfs+记忆路径)

    题意:就是说,给出一个三行三列的数组,其中元素为1--8和x,例如:

    1  2  3    现在,需要你把它变成:1  2  3      要的最少步数的移动方案。可以右移r,左移l,上移u,下移d
    x 4 6 4 5 6
    7 5 8 7 8 x

    思路:这是赤裸裸的康托展开了吧?不知道康托展开的同学可以百度百科........好吧,其实我想说的是,这个题目怎么分析出,要用到康托展开的。首先,遇到这样的题目,元素比较少,又可以用到搜索,但是状态数比较多,也就是说,我需要找到一种方式来压缩这些状态,使得同一个状态不重复出现。额,说道这里,在不考虑时间、空间复杂度的情况下,的确可以直接开标记数组:vist[10][10][10][10][10][10][10][10][10],但是这样一来,会有许多重复的状态。有没有更好压缩状态的方法呢?是有的,进制压缩也是一种方法,只是对于这个题目不适用。那么还有康托展开,康托展开,可以使得这些状态压缩下来,只有9!个状态,如此就可以实现搜索了。

    有的人说,广搜不能记录路径?这是错误的,广搜只要你清楚的记录这个状态的上个状态是什么,那么就可以记录路径,很明显只需要开个记录路径的搜索就ok了

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    int t[10]= {1,1,2,6,24,120,720,5040,40320};
    char ff[400000];
    struct node
    {
        char ch[10];
        int son;
        int wz;
    };
    struct node1        //记录路径
    {
        char num;
        int father;
    } s[362883];
    
    int deal(char str[])       //康托展开
    {
        int x[10],ans1=0;
        for(int i=0; i<9; i++)
            x[i]=str[i]-'0';
    
        /*for(int i=0;i<9;i++)
        printf("%d	",x[i]);*/
    
        for(int i=0; i<9; i++)
        {
            int k=0;
            for(int j=i+1; j<9; j++)
                if(x[i]>x[j])
                    k++;
            ans1+=k*t[8-i];
            //printf("%d  %d  %d
    ",ans1,k,t[8-i]);
        }
        return ans1;
    }
    
    int flag=0;
    void bfs(char str[])
    {
        queue<node>q;
        node p;
        strcpy(p.ch,str);
        p.ch[9]='';
        p.son=deal(p.ch);
        // puts(p.ch);
        p.wz=8;
        //printf("%d
    ",p.son);
        s[p.son].father=0;
    
        q.push(p);
    
        while(!q.empty())
        {
            //flag++;
            //printf("%d
    ",flag);
            p=q.front();
            q.pop();
            int hang=p.wz/3;
            int lie=p.wz%3;
            {
                int x=hang-1;
                int y=lie;
                {
                    int x=hang;
                    int y=lie+1;
                    if(x>=0&&x<3&&y>=0&&y<3&&(x*3+y)<=8)
                    {
                        node p1;
                        strcpy(p1.ch,p.ch);
                        p1.wz=x*3+y;
                        char zf=p1.ch[p.wz];
                        p1.ch[p.wz]=p1.ch[p1.wz];
                        p1.ch[p1.wz]=zf;
                        p1.ch[9]='';
                        p1.son=deal(p1.ch);
                        if(s[p1.son].father==-1)
                        {
                            s[p1.son].father=p.son;
                            s[p1.son].num='l';
                            q.push(p1);
                        }
                    }
                }
    
                {
                    int x=hang;
                    int y=lie-1;
                    if(x>=0&&x<3&&y>=0&&y<3&&(x*3+y)<=8)
                    {
                        node p1;
                        strcpy(p1.ch,p.ch);
                        p1.wz=x*3+y;
                        char zf=p1.ch[p.wz];
                        p1.ch[p.wz]=p1.ch[p1.wz];
                        p1.ch[p1.wz]=zf;
                        p1.ch[9]='';
                        p1.son=deal(p1.ch);
                        if(s[p1.son].father==-1)
                        {
                            s[p1.son].father=p.son;
                            s[p1.son].num='r';
                            q.push(p1);
                        }
                    }
                }
                if(x>=0&&x<3&&y>=0&&y<3&&(x*3+y)<=8)
                {
                    node p1;
                    strcpy(p1.ch,p.ch);
                    p1.wz=x*3+y;
                    char zf=p1.ch[p.wz];
                    p1.ch[p.wz]=p1.ch[p1.wz];
                    p1.ch[p1.wz]=zf;
                    p1.ch[9]='';
                    p1.son=deal(p1.ch);
                    if(s[p1.son].father==-1)
                    {
                        s[p1.son].father=p.son;
                        s[p1.son].num='d';
                        q.push(p1);
                    }
                }
            }
    
            {
                int x=hang+1;
                int y=lie;
                if(x>=0&&x<3&&y>=0&&y<3&&(x*3+y)<=8)
                {
                    node p1;
                    strcpy(p1.ch,p.ch);
                    p1.wz=x*3+y;
                    char zf=p1.ch[p.wz];
                    p1.ch[p.wz]=p1.ch[p1.wz];
                    p1.ch[p1.wz]=zf;
                    p1.ch[9]='';
                    p1.son=deal(p1.ch);
                    if(s[p1.son].father==-1)
                    {
                        s[p1.son].father=p.son;
                        s[p1.son].num='u';
                        q.push(p1);
                    }
                }
            }
    
    
        }
    }
    int main()
    {
        char str[10]= {'1','2','3','4','5','6','7','8','0'};
        for(int i=0; i<362883; i++)
        {
            s[i].father=-1;
        }
        //printf("%d
    ",flag);
        bfs(str);
        char ss[10][10];
        char tt[10];
        scanf("%s",ss[0]);
        {
            if(ss[0][0]!='x')
                tt[0]=ss[0][0];
            else
                tt[0]='0';      //把x转化为数字0
            for(int i=1; i<9; i++)
            {
                scanf("%s",ss[i]);
                if(ss[i][0]!='x')
                    tt[i]=ss[i][0];
                else
                    tt[i]='0';
            }
            tt[9]='';
            //puts(tt);
            int ans=deal(tt);
            int cnt=0;
            flag=0;
            while(ans!=0)        //回溯路径
            {
                ff[cnt++]=s[ans].num;
                ans=s[ans].father;
                if(ans==-1)
                {
                    flag=1;
                    break;
                }
            }
            int i=0;
            if(flag==0)
            {
                while(cnt>i)
                    printf("%c",ff[i++]);
            }
            else   printf("unsolvable");
            printf("
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    pip list报警告DEPRECATION
    JMeter使用ServerAgent监控阿里云服务器连接不上处理方法
    mysql:查询排名
    jmeter教程(二十):性能测试执行及结果分析
    jmeter(二十一)jmeter常用插件介绍
    Jmeter第三方插件Jmeter Plugins
    jmeter 03Jmeter常用插件——梯度加压、响应时间、TPS
    Jenkins 定时任务触发时间表达式 与 cron表达式详解(两者相似但有差异)
    前端语言之JavaScript
    前端语言之CSS样式
  • 原文地址:https://www.cnblogs.com/ziyi--caolu/p/3463797.html
Copyright © 2011-2022 走看看