题解:ABC276E - Round Trip

题解: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开始。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值