zoukankan      html  css  js  c++  java
  • 蓝桥杯——九宫重排(bfs)

    题目:http://lx.lanqiao.cn/problem.page?gpid=T42

    分析:这一题可以对应到“迷宫最短路径”问题,是否能到达终点,若能到达最短步数是多少?用bfs,广度搜索解决,用到队列

    将‘.’作为移动的对象,每移动一次,map[][](九宫格图案)状态改变一次,并且把每一次状态(一定要是新的状态)(定义为结构体node,结构体内容包括:map[][],从最初状态到当前状态移动的步数,‘.’的位置)存入队列que中,每一个map[][]对应一个数值val(将‘.’看做9,从左到右,从上到下抄写)

    如:1 2 3
              4 6
           7 5 8  对应的val值为123946758,这个值用来判断当前map[][]是否出现过(判重,出现过就不计入que,相当于不走这一步了,不走已经走过的情况,不免死循环),每一个不一样的值放入set集合容器中(set可以快速的查询,删除,插入)
    不断取que里队首元素作为移动的起点,新的状态放入队尾,直到队列为空,最终得出的步数即为最短步数。

    代码:

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<set>
      4 #include<queue>
      5 using namespace std;
      6 int Gval;//目标图案对应的值
      7 int D[4][2]= {-1,0,1,0,0,-1,0,1}; //上下左右
      8 struct node
      9 {
     10     int x,y;//‘.’坐标
     11     int step;
     12     char map[3][3];
     13 };
     14 queue<node> que;
     15 set<int> se;
     16 int Get_value(char map[][3]) //得到九宫格图案对应的值
     17 {
     18     int val=0;
     19     for(int i=0; i<3; i++)
     20     {
     21         for(int j=0; j<3; j++)
     22         {
     23             if(map[i][j]!='.')
     24             {
     25                 val=val*10+map[i][j]-'0';//用来字符数字转换成整形数字
     26             }
     27             else
     28             {
     29                 val=val*10+9;
     30             }
     31         }
     32     }
     33     return val;
     34 }
     35 int bfs()
     36 {
     37     node n,n1;
     38     char Nmap[3][3];
     39     int i,j,xx,yy,val;
     40 //如果队列为空,没找到,返回-1
     41     if(que.empty())
     42     {
     43         return -1;
     44     }
     45     while(!que.empty())
     46     {
     47         n=que.front();//取出队首
     48         que.pop();
     49         for( i=0; i<4; i++)
     50         {
     51             xx=n.x+D[i][0];
     52             yy=n.y+D[i][1];
     53             if(xx<0||xx>2||yy<0||yy>2) //越界
     54             {
     55                 continue;
     56             }
     57             //走动了,形成新的图案,查看是否和以前的重了,如果没重,入队列
     58             memcpy(Nmap,n.map,sizeof(n.map));
     59             Nmap[n.x][n.y]=n.map[xx][yy];
     60             Nmap[xx][yy]='.';//新的map
     61             val=Get_value(Nmap);
     62             if(val==Gval) //说明到达了目标状态
     63             {
     64                 return n.step+1;
     65             }
     66             if(se.find(val)==se.end()) //说明set里没有此val,说明与之前的不重复
     67             {
     68                 se.insert(val);//插入val
     69                 n1.x=xx;
     70                 n1.y=yy;
     71                 n1.step=n.step+1;
     72                 memcpy(n1.map,Nmap,sizeof(Nmap));
     73                 que.push(n1);
     74             }
     75         }
     76     }
     77 }
     78 int main()
     79 {
     80     node n;
     81     char str1[15],str2[15],Smap[3][3],Gmap[3][3],ans;
     82     int len=0,i,j,xx,yy;
     83     //读入开始状态,并处理
     84     gets(str1);
     85     for(i=0; i<3; i++)
     86     {
     87         for(j=0; j<3; j++)
     88         {
     89             if(str1[len]=='.')
     90             {
     91                 xx=i;
     92                 yy=j;
     93             }
     94             Smap[i][j]=str1[len];
     95             len++;
     96         }
     97     }
     98     n.x=xx;
     99     n.y=yy;
    100     n.step=0;
    101     memcpy(n.map,Smap,sizeof(Smap));//二维数组复制
    102     que.push(n);
    103     se.insert(Get_value(Smap));
    104     //读入目标状态,并处理
    105     gets(str2);
    106     len=0;
    107     for(i=0; i<3; i++)
    108     {
    109         for(j=0; j<3; j++)
    110         {
    111             Gmap[i][j]=str2[len++];
    112         }
    113     }
    114     Gval=Get_value(Gmap);//目标状态对应的值
    115     ans=bfs();
    116     printf("%d",ans);
    117     return 0;
    118 }
  • 相关阅读:
    vmware虚拟机安装centos,配置PHP、mysql
    Java初学者不得不知的概念,JDK,JRE,JVM的区别?(转)
    char a[] = "hello world1"和char *p = "hello world2";的区别(转)
    关于二维数组传参做形参(转)
    最长连续字母序列的长度(阿里2015在线研发工程师笔试题)
    两个线程并发执行以下代码,假设a是全局变量,那么以下输出______是不可能的?
    软件工程
    面向对象基础
    eclipse
    设计模式(java)--状态模式
  • 原文地址:https://www.cnblogs.com/li-yaoyao/p/10013458.html
Copyright © 2011-2022 走看看