为什么O(nm) 做法 bug 了
查看原帖
为什么O(nm) 做法 bug 了
343531
xiaosi4081楼主2024/8/24 14:30

给个代码(文末有一些解释&疑问)

#include<bits/stdc++.h>
#define int long long
using namespace std;
int opt,n,m;
char s[1005][1005];
int sx,sy,p,q,tx,ty;
int a[1000005],b[1000005];
int c[1000005],d[1000005],vl[1000005];
int flg1[1005][1005],flg2[1005][1005];
struct node{
	int x,y;	
}que[1000005];
int vis[1005][1005];
int vis2[1005][1005];
int l=1,r=0;
int dx[]={0,0,-1,1};
int dy[]={-1,1,0,0};
signed main(){
	ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);
	cin>>opt>>n>>m;
	for(int i=1;i<=n;i++)scanf("%s",s[i]+1);
	cin>>sx>>sy>>p>>q;
	if(opt==1)cin>>tx>>ty;
	for(int i=1;i<=p;i++){
		cin>>a[i]>>b[i];vis[a[i]][b[i]]=1;
		que[++r]={a[i],b[i]};
		flg2[a[i]][b[i]]=i;
	}
	for(int i=1;i<=q;i++)cin>>c[i]>>d[i],flg1[c[i]][d[i]]=i;
	while(l<=r){
		node u=que[l++];
		if(flg1[u.x][u.y]){
			vl[flg1[u.x][u.y]]=vis[u.x][u.y]-1;
			continue;
		}
		for(int i=0;i<4;i++){
			int tx=u.x+dx[i];
			int ty=u.y+dy[i];
			if(tx<1||tx>n||ty<1||ty>m)continue;
			if(vis[tx][ty])continue;
			if(s[tx][ty]=='#')continue;
			vis[tx][ty]=vis[u.x][u.y]+1;
			que[++r]={tx,ty};
		}
	}
	for(int i=1;i<=q;i++)vl[i]+=vl[i-1];
	for(int i=q;i>=1;i--)vl[i]=vl[i-1];
	l=1,r=0;for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)vis[i][j]=0;
	vis[sx][sy]=1;
	int to=0;que[++r]={sx,sy}; 
	while(l<=r){
		node u=que[l++];
		if(flg2[u.x][u.y]){
			to=vis[u.x][u.y]-1;
		}
		for(int i=0;i<4;i++){
			int tx=u.x+dx[i];
			int ty=u.y+dy[i];
			if(tx<1||tx>n||ty<1||ty>m)continue;
			if(vis[tx][ty])continue;
			if(s[tx][ty]=='#')continue;
			vis[tx][ty]=vis[u.x][u.y]+1;
			que[++r]={tx,ty};
		}
	}
	l=1,r=0;
	for(int i=1;i<=q;i++){
		vl[i]+=to;
		if(vis[c[i]][d[i]]-1>vl[i]){
			que[++r]={c[i],d[i]};
			vis[c[i]][d[i]]=vl[i]+1;
		}
	}
	while(l<=r){
		node u=que[l++];
		for(int i=0;i<4;i++){
			int tx=u.x+dx[i];
			int ty=u.y+dy[i];
			if(tx<1||tx>n||ty<1||ty>m)continue;
			if(vis[tx][ty]<=vis[u.x][u.y]+1)continue;
			if(s[tx][ty]=='#')continue;
			vis[tx][ty]=vis[u.x][u.y]+1;
			que[++r]={tx,ty};
		}
	}
	if(opt==0){
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				if(vis[i][j]==0)cout<<"-1 ";
				else cout<<vis[i][j]-1<<" ";
			}
			cout<<"\n";
		}
	}else{
		if(vis[tx][ty]==0)cout<<-1;
		else cout<<vis[tx][ty]-1;
	}
	return 0;
}

思路就是求传送到第 ii 个传送门出口花费的步数(洪水填充+前缀和)

然后最后再继续洪水填充。

最后 0WA。

好像都是输出了负数。

开了 long long,估计是 -1 判的不好

问题是找不到地方(

2024/8/24 14:30
加载中...