• 九宫重排


    问题描述
      如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。

      我们把第一个图的局面记为:12345678.
      把第二个图的局面记为:123.46758
      显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
      本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。
    输入格式
      输入第一行包含九宫的初态,第二行包含九宫的终态。
    输出格式
      输出最少的步数,如果不存在方案,则输出-1。
    样例输入
    12345678.
    123.46758
    样例输出
    3
    样例输入
    13524678.
    46758123.
    样例输出
    22
     
    题解:
      九宫重排,迷宫问题的最短路问题都是可以用广度优先搜索算法来解决的,具体就是以当前状态为起点,遍历其周围的各个结点,把它们分别放在队列中,在对当前状态处理完之后,就可以进行当前状态的迭代了
      注意,上面的"状态"必须的完整的,因为他周围的每个后继状态都需要当前的完整信息,这样才能进行下一次迭代,进行完备的广度搜索.
      对于此题,具体就是:当前矩阵,步数,空格位置.
     
    代码示例:
     
      1 #include<iostream>
      2 #include<queue>
      3 using namespace std;
      4 int dir[]={0,1,0,-1,0};//方向 
      5 int jc[10] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};//0-9的阶乘
      6 bool visit_kt[1000000]={false};//康托visit判断 
      7 struct node
      8 {//状态 
      9     char str[10];
     10     int step;
     11     int spx,spy;
     12 };
     13 bool check(node &start,node &end)
     14 {//检测是否成功 
     15     for(int j=0;j<9;j++)
     16         if(start.str[j]!=end.str[j]) return false; 
     17     return true;
     18  } 
     19 void init(node &start,node &end)
     20 {
     21 //初始态,终态的初始化 
     22     for(int j=0;j<9;j++)
     23     {
     24         scanf("%c",&start.str[j]);
     25         if(start.str[j]=='.') 
     26         {
     27             start.spx=j/3+1;
     28             start.spy=j%3;
     29             start.step=0;
     30         }
     31     }
     32     getchar();
     33     for(int j=0;j<9;j++)
     34     {
     35         scanf("%c",&end.str[j]);
     36         if(end.str[j]=='.') 
     37         {
     38             end.spx=j/3+1; end.spy=j%3;
     39             end.step=0;
     40         }
     41     }
     42 }
     43 void print(string a)
     44 {//打印,状态的矩阵 
     45     cout<<"-------------"<<endl;
     46     for(int i=0;i<3;i++)
     47     {
     48         for(int j=0;j<3;j++)
     49         {
     50             int index=i*3+j;
     51             cout<<a[index]<<" ";
     52         }
     53         cout<<"-----------"<<endl;
     54     }
     55 }
     56 int por(string a)//康托展开
     57 {
     58     int size = 0;
     59     for (int i = 0; i < 9; i++) {
     60         int len = 0;
     61         for (int j = i + 1; j < 9; j++) {
     62             if (a[i] > a[j])len++;
     63         }
     64         size += len * jc[9-i-1];
     65     }
     66     return size;
     67 }
     68 
     69 int main()
     70 {
     71     queue<node> q;
     72     node start,end;
     73     int count=0;
     74     init(start,end);
     75     q.push(start);
     76     if(check(start,end)) 
     77     {//防止数据太狗 
     78         cout<<0<<endl; return 0;
     79     }
     80     while(!q.empty())
     81     {
     82         node local=q.front();
     83         q.pop();
     84         for(int i=0;i<4;i++)
     85         {
     86             node temp=local;
     87             int x=local.spx,y=local.spy;
     88             x=x+dir[i]; y=y+dir[i+1];//后继空格的位置 
     89             if(x<0||x>2||y<0||y>2) continue;
     90             temp.str[3*(local.spx)+local.spy]=temp.str[3*(x)+y];
     91             temp.str[3*(x)+y]='.';
     92             temp.spx=x; temp.spy=y;//空格
     93             /*以上都是为了得出temp结点(状态),*/ 
     94             int index=por(temp.str);//康托值 
     95             if(!visit_kt[index])
     96             {// 
     97                 if(check(temp,end))
     98                 {//判断是否成功 
     99                     cout<<temp.step<<endl;
    100                     cout<<temp.str<<endl;
    101                     return 0;
    102                 }
    103                 visit_kt[index]=true;
    104                 temp.step++;
    105                 q.push(temp);//入队 
    106                 if(count<10)//test it 
    107                     print(temp.str);
    108                 count++;
    109             }
    110         }
    111     }
    112     cout<<"no"<<endl; 
    113     return 0;
    114 }
     
     
     
  • 相关阅读:
    JAVA安装
    capture格式布局
    CSS样式表
    进制的转换
    CentOs7设置主机名称,以及主机名称和ip的对应关系
    CentOS7中NAT网卡设置静态IP
    CentOs7安装配置JDK
    基于Go语言构建区块链:part5
    基于Go语言构建区块链:part4
    BoltDB使用笔记
  • 原文地址:https://www.cnblogs.com/zww-kjj/p/12235291.html
Copyright © 2020-2023  润新知