老实说第一眼看到这个题,脑子里第一时间就想到了BFS,但是最后AC真的十分艰辛,中间遇到了很多奇葩的问题。下面一一道来我在此题的收获
题目传送门
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<map>
#include<queue>
using namespace std;
char a[10];
char b[20];
int dx[] = {
-1,1,0,0};
int dy[] = {
0,0,-1,1};
map<int,string> Map;
queue<string> q;
int find(string s){
for(int i=0;i<s.size();i++){
if(s[i]=='x') return i;
}
}
int getIndex(string s){
int res = 0;
for(int i=0;i<s.size();i++){
if(s[i]=='x') res*=10;
else res = res*10+s[i]-'0';
}
return res;
}
int edx = getIndex("12345678x");
char getChar(int idx){
switch (idx){
case 0:return 'd';
case 1:return 'u';
case 2:return 'r';
case 3:return 'l';
}
}
void init(){
q.push("12345678x");
Map[edx] = "";
while(!q.empty()){
string tem = q.front();
int id = getIndex(tem);
q.pop();
int idx = find(tem);
int i = idx/3;
int j = idx%3;
for(int k=0;k<4;k++){
int x = i+dx[k];
int y = j+dy[k];
if(x<=2&&x>=0&&y<=2&&y>=0){
string ss = tem;
swap(ss[i*3+j],ss[x*3+y]);
int idx = getIndex(ss);
if(Map.count(idx)==0){
Map[idx] = Map[id]+getChar(k);
q.push(ss);
}
}
}
}
}
int main(){
init();
while(gets(b)!=NULL){
int num = 0;
string s;
for(int i=0;i<strlen(b);i++){
if(b[i]!=' ') a[num++] = b[i];
}
s = a;
int sdx = getIndex(s);
if(Map.count(sdx)!=0){
string ss = Map[getIndex(s)];
for(int i=ss.size()-1;i>=0;i--) printf("%c",ss[i]);
printf("\n");
}else{
printf("unsolvable\n");
}
}
system("pause");
}
教训1
以后碰到这种不知道输入多少个用例的以字符串形式接受的题目,不要用Scanf与EOF搭配,因为有空格就不管用(没空格还行),用while(gets(s)!=NULL)
,像我这个sb就遇到了这个问题,一直报错output limiit exceed
(因为一直输入不停止呀md)
教训2
对于map<string,string>可能会超时,以后遇到这样的尽量使用map<int,string>这样的,使用康拓转换也可,实在不行那就nmd直接map<string,string>
教训3
对于有很多数据庸碌输入,要及时每次开始前初始化到正确的状态,切记。
教训4
对于那种把最终状态给你了,初态不太清楚的如果没思路就想着逆向思维。
教训5
一定要仔细呀,nmd,int dx[] = {-1,1,0,0};int dy[] = {0,0,-1,1};这里应改依次对应
{‘d’,‘u’,‘r’,‘l’},不是{‘l’,‘r’,‘d’,‘u’},睁大眼睛看好了,mmp
就这样了,长点心吧,我是废物,呜呜呜呜~~