题解 P2324 【[SCOI2005]骑士精神】
看到大家都用
其实这道题可以用
那答案不是错的嘛?
我们从起始状态做一次打表,我们发现程序计算
也就是双向
利用了把地图转换为一个字符串,然后用
//Copyright (c) 2019 by xiao_mmqueF. All Rights Reserved.
#include<bits/stdc++.h>
#define inl inline
#define reg register
#define INF 0x3f3f3f3f
using namespace std;
inl int read(){ int x=0,f=0; char ch=0; while(!isdigit(ch))f|=(ch=='-'),ch=getchar(); while(isdigit(ch))(x*=10)+=(ch^48),ch=getchar(); return f?-x:x; }
inl void Ot(reg int x) { if(x<0)putchar('-'),x=-x; if(x>=10)Ot(x/10); putchar(x%10+'0'); }
inl void Print(reg int x,char til='\n'){Ot(x);putchar(til);}
inl int Max(reg int x,reg int y){return x>y?x:y;}
inl int Min(reg int x,reg int y){return x<y?x:y;}
inl int Abs(reg int x){return x<0?-x:x;}
struct Node{
int x, y;
string s;
};
map<string, int> mp;
int mv[8][2]={{1,2},{1,-2},{-1,2},{-1,-2},{2,1},{2,-1},{-2,1},{-2,-1}};
string aim="111110111100*110000100000";//目标状态
bool bfs(int x, int y, string s) {
queue<Node> que;
que.push((Node){x, y, s});
mp[s]=1;
while (!que.empty()) {
Node h=que.front();
que.pop();
if (mp[h.s]==8) break;//8步就停
if (h.s==aim) {
Print(mp[h.s]-1);//8步内得到了答案
return true;
}
for (int i=0; i<8; i++) {
int xx=h.x+mv[i][0], yy=h.y+mv[i][1];
if (xx<1 || xx>5 || yy<1 || yy>5) continue;
string tmp=h.s;
int tmp1=(h.x-1)*5+h.y, tmp2=(xx-1)*5+yy;
char tmp_c=tmp[tmp1-1];
tmp[tmp1-1]=tmp[tmp2-1];
tmp[tmp2-1]=tmp_c;
if (mp[tmp]==0) {
mp[tmp]=mp[h.s]+1;
que.push((Node){xx, yy, tmp});
}
}
}
return false;
}
void bfss(int x, int y, string s) {
queue<Node> que;
map<string, int> mpS;
mp[s]=1;
que.push((Node){x, y, s});
mpS[s]=true;
while (!que.empty()) {
Node h=que.front();
que.pop();
if (mp[h.s]==9) {//步数到9了,说明总共超过了15步
Print(-1);//返回无解
return ;
}
for (int i=0; i<8; i++) {
int xx=h.x+mv[i][0], yy=h.y+mv[i][1];
if (xx<1 || xx>5 || yy<1 || yy>5) continue;
string tmp=h.s;
int tmp1=(h.x-1)*5+h.y, tmp2=(xx-1)*5+yy;
char tmp_c=tmp[tmp1-1];
tmp[tmp1-1]=tmp[tmp2-1];
tmp[tmp2-1]=tmp_c;
if (mp[tmp]!=0 && !mpS[tmp]) {//如果与第一次有交集
cout << mp[tmp]-1+mp[h.s] << endl;
return ;
}
if (!mpS[tmp]) {
mp[tmp]=mp[h.s]+1;
que.push((Node){xx, yy, tmp});
mpS[tmp]=true;
}
}
}
}
int main() {
for(reg int T=read();T;T--) {
mp.clear();
string tmp, s="";
int x, y;
for (int i=1; i<=5; i++) {
cin>>tmp;
for (int j=0; j<5; j++)
if (tmp[j]=='*')
x=i, y=j+1;
s+=tmp;//将开始状态作为字符串存储
}
if (!bfs(x, y, s)) bfss(3, 3, aim);
}
return 0;
}