题目描述
给定3行3列的图像各像素点灰度值,给定最终图像,求最短、字典序最小的操作序列。
其中,可能的操作及对应字符有如下四种:
A:顺时针旋转90度;
B:逆时针旋转90度;
C:左右翻转;
D:上下翻转。
输入格式
一个矩阵,表示初始的图像。
一个矩阵,表示最终的图像。
输出格式
最短、字典序最小的操作序列,保证长度不超过100000000,不保证有解(若长度不超过
100000000无解则输出“Poland cannot into space!!!”)。
输入输出样例
输入 #1
3 4 5
6 7 8
1 2 3
1 2 3
6 7 8
3 4 5
输出 #1
D
题意:输入第一个矩阵,能否通过描述的4种变换得到第二个矩阵。
坑点:第一个和第二个矩阵一开始就是一样的。
题解:针对第一个和第二个一开始就一样,直接输出"AB",不然BFS判断一下,为方便记录数据,用字符串记录矩阵数据
AC代码
#include<bits/stdc++.h>
using namespace std;
string A(string s)
{
swap(s[1],s[3]);
swap(s[3],s[7]);
swap(s[7],s[5]);
swap(s[0],s[6]);
swap(s[6],s[8]);
swap(s[8],s[2]);
return s;
}
string B(string s)
{
swap(s[1],s[5]);
swap(s[5],s[7]);
swap(s[7],s[3]);
swap(s[0],s[2]);
swap(s[2],s[8]);
swap(s[8],s[6]);
return s;
}
string C(string s)
{
swap(s[0],s[2]);
swap(s[3],s[5]);
swap(s[6],s[8]);
return s;
}
string D(string s)
{
swap(s[0],s[6]);
swap(s[1],s[7]);
swap(s[2],s[8]);
return s;
}
struct Node{
int dp;
string s;
string C;
};
queue<Node>q;
map<string,int>vis;
vector<string>ct;
void bfs(string s1,string s2)
{
ct.clear();
vis.clear();
while(!q.empty())
q.pop();
int dpmax=100000000;
Node t;
t.s=s1,t.dp=0;
q.push(t);
vis[s1]=1;
while(!q.empty())
{
t=q.front();
q.pop();
for(int i=1;i<=4;i++)
{
Node w=t;
if(i==1)
{
w.s=A(t.s);
w.C.push_back('A');
}
else if(i==2)
{
w.s=B(t.s);
w.C.push_back('B');
}
else if(i==3)
{
w.s=C(t.s);
w.C.push_back('C');
}
else
{
w.s=D(t.s);
w.C.push_back('D');
}
w.dp=t.dp+1;
if(vis[w.s]>0)continue;
vis[w.s]=1;
if(w.dp>dpmax)continue;
if(w.s==s2)
{
dpmax=min(dpmax,w.dp);
ct.push_back(w.C);
continue;
}
q.push(w);
}
}
if(dpmax==100000000)
puts("Poland cannot into space!!!");
else{
sort(ct.begin(),ct.end());
cout<<ct[0]<<endl;
}
}
int main()
{
string s1,s2;
for(int i=1;i<=3;i++)
{
for(int j=1;j<=3;j++)
{
char c;
cin>>c;
s1.push_back(c);
}
}
for(int i=1;i<=3;i++)
{
for(int j=1;j<=3;j++)
{
char c;
cin>>c;
s2.push_back(c);
}
}
if(s1==s2)
cout<<"AB\n";
else
bfs(s1,s2);
return 0;
}