FOJ FZU 2028 时空门问题

因为这道题交了不能判了,好像oj没了,所以自己测不了,一下是大佬的博客

 一道bfs+vector的题->https://blog.csdn.net/qq_32866009/article/details/51090266

注意博主提的三个挖点

因为数据太大,用了二维的vector,学到了这个

然后就是bfs搜索一定要一层一层搜,不要胡搜

以下是我胡搜的代码,当然答案也是错的(bfs实质是一层一层搜,我是找到跳跃点就搜就入队列,有点像dfs了),以后回头对比着看吧,

#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<stdlib.h>
#include<queue>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1005;
struct node{
	int x,y;
	int s;
}; 
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
vector<int>v[maxn][maxn];
int vis[maxn][maxn];
char e[maxn][maxn];
int n,m;
int s1,e1;
int s2,e2;
bool judge(int x,int y){
	if(x>=0&&x<n&&y>=0&&y<m&&vis[x][y]==0&&e[x][y]!='#')
		return true;
	return false;
} 
void bfs(int x,int y){
	vis[x][y]=1;
	struct node now,t;
	now.x=x;
	now.y=y;
	now.s=0;
	queue<node>q;
	q.push(now);
	for(int p=0;p<v[x][y].size();p=p+2){
		int nxx=v[x][y][p];
		int nyy=v[x][y][p+1];
		if(judge(nxx,nyy)){
            vis[nxx][nyy]=1;
			t.s=now.s+1;
		    t.x=nxx;
			t.y=nyy; 
			q.push(t);					  	
 		}	
	}
	while(!q.empty()){
		now=q.front();
		q.pop();
		if(now.x==s2&&now.y==e2){
			cout<<now.s<<endl;
			return ;
		}
		for(int i=0;i<4;i++){
			int nx=now.x+dx[i];
			int ny=now.y+dy[i];
			if(judge(nx,ny)){//判断该点是否可以走 
			    vis[nx][ny]=1;
			    if(v[nx][ny].size()!=0){
			    	for(int p=0;p<v[nx][ny].size();p=p+2){//判断时空门 
					  int nxx=v[nx][ny][p];
					  int nyy=v[nx][ny][p+1];
					  if(judge(nxx,nyy)){
                         vis[nxx][nyy]=1;
						 t.s=now.s+2;
						 t.x=nxx;
						 t.y=nyy; 
						 q.push(t);					  	
 					  }	
				    }
				}
				else{
					t.s=now.s+1;
					t.x=nx;
					t.y=ny;
					q.push(t);
				}	
			} 
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=0;i<n;i++){
		getchar();
		for(int j=0;j<m;j++){
			cin>>e[i][j];
		}
	}
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			if(e[i][j]=='s'){
				s1=i;
				e1=j;
			}
			if(e[i][j]=='t'){
				s2=i;
				e2=j;
			}
		}
	} 
	for(int i=0;i<n;i++)
	    for(int j=0;j<n;j++){
	   	    int k;
	   		cin>>k;
	   		for(int o=0;o<k;o++){
	   			int x,y;
	   			cin>>x>>y;
	   			x--;//图是从 下标为0开始的 
	   			y--;//而输入的点下标从1开始 
	   			v[i][j].push_back(x);//每一个点的时空门的一对坐标以此压进去 
				v[i][j].push_back(y);    
			   }
		}
	bfs(s1,e1);
	return 0;
}

正确的核心代码是 应该是先把当前点的四个方向压进队列,再把时空门跳跃的点压进队列,一层一层的搜

while(!q.empty()){
		now=q.front();
		q.pop();
		if(now.x==s2&&now.y==e2){
			cout<<now.s<<endl;
			return ;
		}
		for(int i=0;i<4;i++){
			int nx=now.x+dx[i];
			int ny=now.y+dy[i];
			if(judge(nx,ny)){//判断该点是否可以走 
			    vis[nx][ny]=1;
					t.s=now.s+1;
					t.x=nx;
					t.y=ny;
					q.push(t);
			}	
		}
		for(int p=0;p<v[nx][ny].size();p=p+2){//判断时空门 
			int nxx=v[nx][ny][p];
			int nyy=v[nx][ny][p+1];
			if(judge(nxx,nyy)){
                vis[nxx][nyy]=1;
				t.s=now.s+1;
				t.x=nxx;
				t.y=nyy; 
				q.push(t);					  	
 			}	
		}
	}
}

猜你喜欢

转载自blog.csdn.net/gml1999/article/details/84192325