代码源集训复盘Day5

代码源集训复盘

Day5(7.25):搜索

image.png

A Gym - 105941F

最难绷的一道卡常题,不知道为什么用队列写BFS会T,用递归不会。。。

首先特判一下能不能直接走到,如果可以直接输出 0 0 0 即可

( 1 , 1 ) (1,1) (1,1) 能走到的所有障碍物,设置成源点,放进队列,把 ( n , m ) (n,m) (n,m) 能走到的所有非障碍物,设置成终点。

因为边权是 1 1 1,所以BFS即可,当然也可以用dijkstra。

int n,m;
char c[1005][1005];
int vis[1005][1005],dis[1005][1005];
int dx[4]={
   
   0,0,-1,1},dy[4]={
   
   -1,1,0,0};
queue<pii> que;
void bfs1(pii st,int mk){
   
   //递归版
    vis[st.fi][st.se]=1;
    for(int i=0;i<4;i++){
   
   
        int a=st.fi+dx[i],b=st.se+dy[i];
        if(a>=1 && a<=n && b>=1 && b<=m && !vis[a][b]){
   
   
            if(c[a][b]=='.') bfs1({
   
   a,b},mk);
            else if(mk==0){
   
   
                que.push({
   
   a,b});
                dis[a][b]=1;
                vis[a][b]=1;
            }
        } 
    }
}
void bfs(pii st,int f){
   
   //队列版
	queue<pii> q;
	q.push(st);
	vis[st.fi][st.se]=1;
	while(!q.empty()){
   
   
		auto h=q.front();
		q.pop();
		vis[h.fi][h.se]=1;
		for(int i=0;i<4;i++){
   
   
			int tx=h.fi+dx[i],ty=h.se+dy[i];
			if(1<=tx&&tx<=n&&1<=ty&&ty<=m&&c[tx][ty]=='.'&&!vis[tx][ty])
				q.push({
   
   tx,ty});
			else if(f==0&&1<=tx&&tx<=n&&1<=ty&&ty<=m&&c[tx][ty]=='#'&&!vis[tx][ty])
				que.push({
   
   tx,ty}),dis[tx][ty]=1,vis[tx][ty]=1;
		}
	}
}
int ans=1e18;
void bfs2(){
   
   
	while(!que.empty()){
   
   
		auto h=que.front();
		que.pop();
		for(int i=0;i<4;i++){
   
   
			int tx=h.fi+dx[i],ty=h.se+dy[i];
			if(1<=tx&&tx<=n&&1<=ty&&ty<=m){
   
   
				if(!vis[tx][ty]&&dis[h.fi][h.se]+1<dis[tx][ty]){
   
   
					dis[tx][ty]=dis[h.fi][h.se]+1;
					que.push({
   
   tx,ty});
				}
				if(vis[tx][ty]&&dis[h.fi][h.se]<dis[tx][ty]){
   
   
					// cout<<tx<<' '<<ty<<endl;
					dis[tx][
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值