POJ3322(bfs+细节处理)

先骂一句傻逼评测机 T了一下午 去入门OJ交终于A掉了 800+ms,对于2000ms的时限我怎么都想不通POJ怎么会T掉

就是一个傻逼bfs,注意横着和竖着的情况,处理比较麻烦的是对于两个点(ax,ay)和(bx,by),如何打标记

我原来的思路就是开一个结构体root,然后map映射过去,后来发现被T的死死的,手造大样例跑了2.5s。又想到另一个基于hash映射的写法,把4个数看成500进制数,再开映射,不过貌似跑快了些还是很慢。

然后加上mod和散列表,这图太稠密跑的太慢。今天都写这一个题了 一直在想优化 果然是我太菜了。

最后想到的是开a[N][N][5],其中0表示站着,1向右,2向上,3向左,4向下。

细节把我恶心到了 其实打完还是挺快的 代码能力太菜了

贴代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
using namespace std;
#define rint register int
const int N=2e6+5;
struct node{
	int fromx,tox,fromy,toy,x,ans;
	node(){fromx=tox=fromy=toy=x=0;}
}que[N],E;
int b[505][505][5],flag;
char aa[505];
int a[505][505],dx[4]={0,1,0,-1},dy[4]={1,0,-1,0};
int head=1,tail=1;
inline void pd(rint fx,rint fy,rint tx,rint ty,rint type,rint ans){
	rint now=0;
	if(fx==tx){fx-=type,tx-=type;if(fy>=ty) now=3;else now=1;}
	else{fy-=type,ty-=type;if(fx>=tx) now=4;else now=2;} 
	if(a[fx][fy]&&a[tx][ty]&&!b[fx][fy][now]){ 
		tail++;if(tail==2000000) tail=1;
		que[tail].fromx=fx,que[tail].tox=fy,que[tail].fromy=tx,que[tail].toy=ty,que[tail].x=1,que[tail].ans=ans+1,b[fx][fy][now]=1;
	}
}inline void work(rint fx,rint fy,rint tx,rint ty,rint type,rint ans){
	rint nowx,nowy;
	if(fx==tx&&type==1) nowx=fx,nowy=max(fy,ty)+1;
	if(fx==tx&&type==-1) nowx=fx,nowy=min(fy,ty)-1;
	if(fy==ty&&type==1) nowy=fy,nowx=max(fx,tx)+1;
	if(fy==ty&&type==-1) nowy=fy,nowx=min(fx,tx)-1;
	if(a[nowx][nowy]==2&&!b[nowx][nowy][0]){
		tail++;if(tail==2000000) tail=1;
		que[tail].fromx=nowx,que[tail].tox=nowy,b[nowx][nowy][0]=0,que[tail].ans=ans+1;
		if(que[tail].fromx==E.fromx&&que[tail].tox==E.tox&&!que[tail].fromy){
				printf("%d\n",que[tail].ans);flag=1;return;
		}
	}
}
int main(){
	freopen("1.in","r",stdin);
	freopen("1.out","w",stdout);
	rint n,m;
	while(1){
		memset(a,0,sizeof(a));
		memset(que,0,sizeof(que));
		head=tail=1;memset(b,0,sizeof(b));flag=0;
		scanf("%d%d",&n,&m);
		if(n==m&&n==0) return 0;
		for(rint i=1;i<=n;i++){
			scanf("%s",aa+1);
			for(rint j=1;j<=m;j++)
			if(aa[j]=='#') a[i][j]=0;
			else if(aa[j]=='.') a[i][j]=2;
			else if(aa[j]=='E') a[i][j]=1;
			else if(!que[1].x&&aa[j]=='X') que[1].x=1,que[1].fromx=i,que[1].tox=j,a[i][j]=2;
			else if(que[1].x&&aa[j]=='X') que[1].fromy=i,que[1].toy=j,a[i][j]=2;
			else E.fromx=i,E.tox=j,a[i][j]=2;
		}if(!que[1].fromy) que[1].x=0;
		while(head<=tail){
			rint fx=que[head].fromx;
			rint fy=que[head].tox,ans=que[head].ans;
			rint tx=que[head].fromy;
			rint ty=que[head].toy,x=que[head].x;
			if(head==4){
				rint w=1;
			} 
			if(x){
				pd(fx,fy,tx,ty,1,ans),pd(fx,fy,tx,ty,-1,ans);
				work(fx,fy,tx,ty,1,ans);if(flag) break;
				work(fx,fy,tx,ty,-1,ans);if(flag) break;
			}else{
				for(rint i=0;i<=3;i++){
					rint ax=fx+dx[i],ay=fy+dy[i];
					rint bx=fx+dx[i]*2,by=fy+dy[i]*2;rint now=i+1;
					if(a[ax][ay]&&a[bx][by]&&!b[ax][ay][now]){
						tail++;if(tail==2000000) tail=1;
						que[tail].fromx=ax,que[tail].tox=ay,que[tail].fromy=bx,que[tail].toy=by,que[tail].x=1,que[tail].ans=ans+1,b[ax][ay][now]=1;
					}
					
				}
			}head++;if(head==2000000) head=1;
		}if(!flag) printf("Impossible\n");
	}
		
}
posted @ 2018-08-19 20:50  BLUE_EYE  阅读(529)  评论(0)    收藏  举报