题解:ABC276E - Round Trip
·题目
链接:Atcoder。
链接:洛谷。
·难度
算法难度:普及。
思维难度:提高。
调码难度:提高。
综合评价:困难。
·算法
bfs。
·思路
从起点周围四个点中任选两个可以走的(记为点1、点2),判断他们两个在不经过起点的情况下是否连通(当然是用bfs判断),由于该两个点之间路径长度至少为2(见图1),所以该回路总长度一定不少于4(起点—{1}—点1—{不少于2}—点2—{1}—起点)。因此,只要有任意两个点可以并经过起点并且互相联通,就应该输出Yes,否则输出No。
·代价
O(N+M)。
·细节
由于数据大小不确定,对于存储问题可以用vector、string、map等实现。
·代码
#include<bits/stdc++.h>
#define N 1100000
using namespace std;
struct Node{int d,x,y;
};
map<pair<int,int>,bool>see;
string mp[N]={};
Node q[N]={};
int c[4][2]={{-1,0},{0,-1},{0,1},{1,0}},h=0,w=0,x=0,y=0;
char in[N]={};
bool can_get(int ax,int ay,int bx,int by);
int main(){scanf("%d%d",&h,&w);for(int i=1;i<=h;i++){scanf("%s",in);mp[i]=in;}for(int i=1;i<=h;i++){mp[i]=' '+mp[i];for(int j=1;j<=w;j++){if(mp[i][j]=='S'){x=i;y=j;}}}for(int i=0;i<4;i++){for(int j=i+1;j<4;j++){int ax=x+c[i][0],ay=y+c[i][1],bx=x+c[j][0],by=y+c[j][1];if(mp[ax][ay]!='#'&&mp[bx][by]!='#'){if(can_get(ax,ay,bx,by)==true){printf("Yes\n");return 0;}}}}printf("No\n");return 0;
}
bool can_get(int ax,int ay,int bx,int by){see.clear();int front=1,rear=0;rear++;q[rear]={0,ax,ay};see[{ax,ay}]=true;while(front<=rear){Node now=q[front];if(now.x==bx&&now.y==by){return true;}for(int i=0;i<4;i++){int nx=now.x+c[i][0],ny=now.y+c[i][1];if(see[{nx,ny}]==true||nx<1||ny<1||nx>h||ny>w||nx==x&&ny==y||mp[nx][ny]=='#'){continue;}else{see[{nx,ny}]=true;rear++;q[rear]={now.d+1,nx,ny};}}front++;}return false;
}
·注意
bfs内移动时要考虑边界、障碍物、是否在起点等问题;输出Yes后一定要及时退出程序;string存储时一定要注意是从0还是1开始。