三阶平面魔方(BFS)

三阶平面魔方(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\n":"%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\n",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\n");//不能成功 
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 }

 

 

-

posted @ 2020-01-13 17:41  jiamian22  阅读(1007)  评论(1编辑  收藏  举报