题意:
(输入两个点的坐标,分别代表黑马和白马的当前位置)
有两匹马,可以走“日”和“田”,问从当前的位置走到(1,1)点的最小步数
分析:
(本人蒟蒻)
刚开始不知道从什么地方下手,从马的位置到(1,1)的位置,一定会用到搜索,(然后我就立马敲起了代码,但是敲的深搜,当然超时!!!:因为深搜对于某个点会一直往下搜索,而不是像新冠病毒那样同时扩散,搜到的结果肯定不是正确的;所以偷偷的点开了算法标签,发现是广搜,嘻嘻)
想到可以从(1,1)往外搜,搜索两次,如果碰到黑马或者白马就可以return ,由于题目表述的有点问题(我个人认为,嘻嘻),发现还是爆了两个点,其实是不能跳到坐标轴上,把边界条件改一下就OK了
哈哈哈
***AC代码***
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
#define de(x) cout<<x<<" ";
#define Pu puts("");
#define sf(x) scanf("%lld",&x);
#define int long long
const int N=1e5+10,inf=0x3f3f3f3f3f3f3f3f;
int dx[]={-2,-2,-2,-2,-1,-1,2,2,2,2,1,1};
int dy[]={2,1,-2,-1,-2,2,2,1,-2,-1,2,-2};
int vis[55][55];
int x1,y11,x2,y2;
struct node{
int x,y,dep;
};
queue<node>q;
int an1=inf,an2=inf;
bool valid(int x,int y){
if(x>50||y>50||x<=0||y<=0) return 0;
return 1;
}
void bfs(int op){
//dbg(x)dbg(y)Pu
node now,nxt;
int x,y;
while(q.size()){
now=q.front();q.pop();
x=now.x,y=now.y;
if(x==x1&&y==y11&&op==1){
an1=min(an1,now.dep);
return ;
}
if(x==x2&&y==y2&&op==2){
an2=min(an2,now.dep);
return ;
}
for(int i=0;i<12;i++){
int l=x+dx[i];
int r=y+dy[i];
if(!valid(l,r)||vis[l][r]) continue;
vis[l][r]=1;
nxt.x=l,nxt.y=r,nxt.dep=now.dep+1;
//de(l)de(r)Pu
q.push(nxt);
}
}
}
signed main(){
node st;
cin>>x1>>y11>>x2>>y2;
//st1.dep=st2.dep=0;
st.x=1;st.y=1;st.dep=0;//从1,1往外走
memset(vis,0,sizeof(vis));
vis[1][1]=1;
q.push(st);//第一匹马
bfs(1);
while(q.size()) q.pop();
memset(vis,0,sizeof(vis));
vis[1][1]=1;
q.push(st);//第二匹马
bfs(2);
printf("%lld\n%lld\n",an1,an2);
}