提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
BFS一般步骤:
1.设置起点目标,起点入队,标记起点
2.搜索队首,若队首是目标,算法结束;否则队首的邻接点**(满足条件且未被标记)**入队,并标记。
3.队首出队;
4.若队列非空,回到步骤2.
一、题目
二、思路
两次BFS暴搜即可。
1.BFS八个方向
int dir[8][2]={{-2,-1},{-2,+1},{-1,+2},{+1,+2},
{+2,-1},{+2,+1},{+1,-2},{-1,-2}};
只有 C h n i e s e C h e s s Chniese Chess ChnieseChess 需要判定蹩马腿。 ( t y p e = = 1 ) (type==1) (type==1)代表 C h n i e s e C h e s s Chniese Chess ChnieseChess的BFS
if(type==1&&ma_jiao(i,tar.x,tar.y)){
continue;
}
if(nx<1||nx>n||ny<1||ny>m)continue;
if(vis[nx][ny]==1)continue;
if(has_sth[nx][ny]==0){
q.push({nx,ny,tar.nu+1});
vis[nx][ny]=1;
}
注意 C h n i e s e C h e s s Chniese Chess ChnieseChess的入队的条件:没有标记过、在棋盘内、目的地没有棋子、没有蹩马腿。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=1e9+7;
const int maxn=307;
short int vis[maxn][maxn];
short int has_sth[maxn][maxn];
ll num=inf;
short int flag;
int n,m,c,d;
int dir[8][2]={{-2,-1},{-2,+1},{-1,+2},{+1,+2},
{+2,-1},{+2,+1},{+1,-2},{-1,-2}};
//bool is_in(int x,int y){if(x>=1&&x<=n&&y>=1&&y<=m)return true;else return false;}
struct node{int x;int y;int nu;};
int ma_jiao(int id,int xx,int yy){
if(id==0||id==1)//up
{
if(has_sth[xx-1][yy]==1){
//cout<<xx-1<<" "<<yy<<" has sth\n";
return 1;
}
else{
return 0;
}
}
if(id==2||id==3)//right
{
if(has_sth[xx][yy+1]==1){
//cout<<xx<<" "<<yy+1<<" has sth\n";
return 1;
}
else{
return 0;
}
}
if(id==4||id==5)//down
{
if(has_sth[xx+1][yy]==1){
//cout<<xx+1<<" "<<yy<<" has sth\n";
return 1;
}
else{
return 0;
}
}
if(id==6||id==7)//left
{
if(has_sth[xx][yy-1]==1){
//cout<<xx<<" "<<yy-1<<" has sth\n";
return 1;
}
else{
return 0;
}
}
return 404;
}
void mine(int x,int y,int nu,int type){//0 for/ 1 mine
queue<node>q;
q.push({x,y,nu});
while(!q.empty()){
node tar=q.front();
vis[tar.x][tar.y]=1;
q.pop();
if(tar.x==c&&tar.y==d){
flag=1;
num=tar.nu;
return;
}
int nx,ny;
for(ll i=0;i<=7;i++){
short int nx=tar.x+dir[i][0];
short int ny=tar.y+dir[i][1];
if(type==1&&ma_jiao(i,tar.x,tar.y)){
continue;
}
if(nx<1||nx>n||ny<1||ny>m)continue;
if(vis[nx][ny]==1)continue;
if(has_sth[nx][ny]==0){
q.push({nx,ny,tar.nu+1});
vis[nx][ny]=1;
}
}
}
}
void init(int a,int b){
flag=-1;num=inf;
for(int i=0;i<=a;i++){
for(int j=0;j<=b;j++)vis[i][j]=0;
}
}
int main(){
int t;
cin>>t;
while(t--){
int k,a,b;
cin>>n>>m>>k>>a>>b>>c>>d;
memset(has_sth,0,sizeof(has_sth));
for(int i=1;i<=k;i++){
int xx,yy;
cin>>xx>>yy;
has_sth[xx][yy]=1;
}
init(n,m);
vis[a][b]=1;
mine(a,b,0,0);
vis[a][b]=0;
if(flag==-1){
cout<<-1<<" ";
}
else cout<<num<<" ";
init(n,m);
mine(a,b,0,1);
if(flag==-1){
cout<<-1<<endl;
}
else cout<<num<<endl;
}
return 0;
}
/*BFS复习*/
总结
DFS超时,就用BFS。若BFS还炸内存,注意入队条件。入队时即给每个元素做访问标记。