zoukankan      html  css  js  c++  java
  • 三阶平面魔方(BFS)

    有一个  3×3 的平面魔方,在平面魔方中,每个格子里分别无重复地写上 1 - 9 这 9 个数字。一共有 4 种对平面魔方的操作:

    • 选择某一行左移。
    • 选择某一行右移。
    • 选择某一列上移。
    • 选择某一列下移。

    初始状态为


    123

    456

    789

    比如选择第一行左移,魔方会变成下面这样

    231

    456

    789

    现在给出魔方的一个状态,问你能否将魔方复原成初始状态。如果可以,计算最少操作次数。

    输入格式

    输入三行,每行三个 1 到 9 之间的整数。

    输出格式

    如果能还原成初始状态,输出最小的操作次数,否则输出 -1。

    样例输入

    412
    756
    389

    样例输出

    2 

    将魔方的状态转为数字,然后再用结构体存储,去进行状态变换,然后就是用map来判重并存操作数

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <iostream>
      4 #include <string>
      5 #include <math.h>
      6 #include <algorithm>
      7 #include <vector>
      8 #include <stack>
      9 #include <queue>
     10 #include <set>
     11 #include <map>
     12 #include <sstream>
     13 const int INF=0x3f3f3f3f;
     14 typedef long long LL;
     15 const int maxn=1e7+10;
     16 using namespace std;
     17 
     18 struct node
     19 {
     20     int a[4][4];
     21     bool operator < (const node &ts) const //map需要 
     22     {
     23         for(int i=1;i<=3;i++)
     24         {
     25             for(int j=1;j<=3;j++)
     26             {
     27                 if(a[i][j]<ts.a[i][j])
     28                     return 1;
     29             }
     30         }
     31         return 0;
     32     }
     33     bool operator == (const node &ts) const //用于出递归 
     34     {
     35         for(int i=1;i<=3;i++)
     36         {
     37             for(int j=1;j<=3;j++)
     38             {
     39                 if(a[i][j]!=ts.a[i][j])
     40                     return 0;
     41             }
     42         }
     43         return 1;
     44     }
     45     void print()
     46     {
     47         for(int i=1;i<=3;i++)
     48         {
     49             for(int j=1;j<=3;j++)
     50             {
     51                 printf(j==3?"%d
    ":"%d",a[i][j]);
     52             }
     53         }
     54     }
     55     int tonum()//返回一个代表魔方状态的int 
     56     {
     57         int res=0;
     58         for(int i=1;i<=3;i++)
     59         {
     60             for(int j=1;j<=3;j++)
     61             {
     62                 res=res*10+a[i][j];
     63             }
     64         }
     65         return res;
     66     }
     67 };
     68 node last;
     69 
     70 node rotate(node u,int num,int op)//获取魔方的下一个状态 
     71 {
     72     node res=u;
     73     if(op==-1)//右移 
     74     {
     75         swap(res.a[num][1],res.a[num][2]);
     76         swap(res.a[num][1],res.a[num][3]);
     77     }
     78     else if(op==1)//左移 
     79     {
     80         swap(res.a[num][2],res.a[num][3]);
     81         swap(res.a[num][1],res.a[num][3]);
     82     }
     83     else if(op==-2)//上移 
     84     {
     85         swap(res.a[2][num],res.a[3][num]);
     86         swap(res.a[1][num],res.a[3][num]);
     87     }
     88     else if(op==2)//下移 
     89     {
     90         swap(res.a[1][num],res.a[2][num]);
     91         swap(res.a[1][num],res.a[3][num]);
     92     }
     93     return res;
     94 }
     95 
     96 void BFS(node first)
     97 {
     98     queue<node> qe;
     99     map<int,int> mp;//判断某一状态是否出现过,并且记录操作数 
    100     qe.push(first);
    101     mp[first.tonum()]=0;
    102     while(!qe.empty())
    103     {
    104         node t=qe.front();
    105         qe.pop();
    106         int tt=t.tonum();
    107         if(t==last)
    108         {
    109             printf("%d
    ",mp[t.tonum()]);
    110             return ;
    111         }
    112         node to;
    113         for(int i=1;i<=3;i++)
    114         {
    115             to=rotate(t,i,-1);
    116             if(!mp.count(to.tonum()))
    117             {
    118                 mp[to.tonum()]=mp[tt]+1;
    119                 qe.push(to);
    120             }
    121             to=rotate(t,i,1);
    122             if(!mp.count(to.tonum()))
    123             {
    124                 mp[to.tonum()]=mp[tt]+1;
    125                 qe.push(to);
    126             }
    127             to=rotate(t,i,-2);
    128             if(!mp.count(to.tonum()))
    129             {
    130                 mp[to.tonum()]=mp[tt]+1;
    131                 qe.push(to);
    132             }
    133             to=rotate(t,i,2);
    134             if(!mp.count(to.tonum()))
    135             {
    136                 mp[to.tonum()]=mp[tt]+1;
    137                 qe.push(to);
    138             }
    139         }
    140     }
    141     printf("-1
    ");//不能成功 
    142 }
    143 
    144 int main()
    145 {
    146     #ifdef DEBUG
    147     freopen("sample.txt","r",stdin);
    148     #endif
    149     
    150     for(int i=1;i<=3;i++)
    151     {
    152         for(int j=1;j<=3;j++)
    153         {
    154             last.a[i][j]=(i-1)*3+j;
    155         }
    156     }
    157     node first;
    158     for(int i=1;i<=3;i++)
    159     {
    160         int n;
    161         scanf("%d",&n);
    162         first.a[i][3]=n%10;
    163         first.a[i][2]=(n/10)%10;
    164         first.a[i][1]=n/100;
    165     }
    166     BFS(first);
    167     
    168     return 0;
    169 }

    -

  • 相关阅读:
    python解压缩rar,zip文件的正确姿势
    tensorflow1.x及tensorflow2.x不同版本实现验证码识别
    qt5.6.3下使用firebird
    Python3.6下的Requests登录及利用Cookies登录
    c++实现全密码生成
    android中利用HttpURLConnection进行Get、Post和Session读取页面。
    Freebsd10.3 Nginx多版本PHP
    Freebsd10.3(FreeBSD11 Beta1)使用手记
    Eclipse导入的User Libarary
    MySQL zip版本安装
  • 原文地址:https://www.cnblogs.com/jiamian/p/12188416.html
Copyright © 2011-2022 走看看