其他分享
首页 > 其他分享> > 穿越

穿越

作者:互联网

穿越

题目背景

imageimageimageimage

解决方法

定义

定义以下变量:

  1. $ mapp[n][m] $ 储存基本地图
  2. \(rain[n][m]\) 下雨时间
  3. \(bear[n][m]={t1,t2}\) 怪兽出没时间段
  4. \(ans~time[n][m]\) 每个点的最优时间

小技巧1:可以将\(mapp[n][m]\)的四周围上\(1\),这样就可以不用判是否出界。

小技巧2:定义变量\(X[5]={0,1,0,-1,0}~~Y[5]={0,0,-1,0,1}\)。可以循环来上下左右走。

分类讨论

设当前下一步走的位置为\((nx,ny)\),时间为\(t\)。

  1. \(mapp[nx][ny]==1\) 不可走。

  2. \(mapp[nx][ny]!=1\)

    1. \(mapp[nx][ny]==0\)

    直接判断是否有洪水,还有是否最佳(\(t<ans~time[nx][ny]\))

    1. \(mapp[nx][ny]==2\)

      1. 不走传送门同2.a

      2. 走传送门

        判断目的地是否有洪水,是否为最优

    2. \(mapp[nx][ny]==3\)

      1. 先判断有无洪水,若有结束

      2. 判断怪兽是否苏醒

        苏醒:等待直到其睡觉(判断洪水)

        睡觉:当作空地

CODE

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 300+32;
int int_maxn=1e9;
ll ll_maxn=1e18;
inline ll read_int(){
    ll a=0,f=0,g=getchar();
    while(g<'0'||g>'9'){if(g=='-') f=1;g=getchar();}
    while('0'<=g&&g<='9') a=a*10+g-'0',g=getchar();
    return f ? -a : a;
}
inline void write(ll s,bool f){
    int top=0,a[40];
    if(s<0) s=-s,putchar('-');
    while(s) a[++top]=s%10,s/=10;
    if(top==0) a[++top]=0;
    while(top) putchar(a[top]+'0'),top--;
    if(f) putchar('\n');
}

int mapp[maxn][maxn];
int n,m;
struct BEAR{
	int t1,t2;
	inline bool check(int t) {return !(t1<=t&&t<=t2);}
}bear[maxn][maxn];

struct send{
	int x,y;
}to[maxn];
int cnt;
int ans_time[maxn][maxn];
int rain[maxn][maxn];
struct ZT{
	int x,y,time;
};

const int X_[6]={0,1,0,-1,0};
const int Y_[6]={0,0,-1,0,1};

inline void read(){
	memset(rain,0x3f,sizeof rain);
	memset(ans_time,0x3f,sizeof ans_time);
	n=read_int(),m=read_int();
	for(int i=1;i<=n;i++){
		for(int e=1;e<=m;e++){
			mapp[i][e]=read_int();
			if(mapp[i][e]==3) to[++cnt]=(send){i,e};
		}
	}
	for(int i=1;i<=n;i++) mapp[i][0]=mapp[i][m+1]=1;
	for(int i=1;i<=m;i++) mapp[0][i]=mapp[n+1][i]=1;
	int a=read_int();
	for(int i=1;i<=a;i++){
		int t=read_int();
		int p=read_int();
		for(int e=1;e<=p;e++){
			int x=read_int(),y=read_int();
			rain[x][y]=min(rain[i][e],t);
		}
	}
	int b=read_int();
	for(int i=1;i<=b;i++){
		int t1=read_int(),t2=read_int(),x=read_int(),y=read_int();
		bear[x][y]=BEAR{t1,t2};
	}
	queue<ZT> p;
	p.push((ZT){1,1,0});
	ans_time[1][1]=0;
	while(!p.empty()){
		int x=p.front().x,y=p.front().y,t=ans_time[x][y];
		 p.pop();
//		 if(ans_time[x][y]!=t) continue;
//		 if(x==n&&y==m) {write(ans,1);return;}
		 for(int i=1;i<=4;i++){
		 	int X=x+X_[i],Y=y+Y_[i];
		 	if(mapp[X][Y]!=1){
		 		if(mapp[X][Y]==0){
		 			if(t+1<ans_time[X][Y]&&t+1<rain[X][Y]){
		 				ans_time[X][Y]=t+1;
		 				p.push(ZT{X,Y,t+1});
					 }
				 }
				 if(mapp[X][Y]==2){
				 	if(t+1<rain[X][Y]){
				 		if(bear[X][Y].check(t+1)==0){
				 			if(bear[X][Y].t2+1<ans_time[X][Y]&&bear[X][Y].t2+1<rain[X][Y]){
				 				ans_time[X][Y]=bear[X][Y].t2+1;
				 				p.push((ZT){X,Y,ans_time[X][Y]});
							 }
						 }
						 else if(ans_time[X][Y]>t+1){
						 	ans_time[X][Y]=t+1;
						 	p.push((ZT){X,Y,t+1});
						 }
					 }
				 }
				 if(mapp[X][Y]==3){
				 	if(t+1<rain[X][Y]&&ans_time[X][Y]>t+1){
				 		ans_time[X][Y]=t+1;
				 		p.push((ZT){X,Y,t+1});
					 }
					 if(t+1<rain[X][Y]){
					 	for(int e=1;e<=cnt;e++){
					 		if(t+3<ans_time[to[e].x][to[e].y]&&t+3<rain[to[e].x][to[e].y]){
					 			ans_time[to[e].x][to[e].y]=t+3;
					 			p.push((ZT){to[e].x,to[e].y,t+3});
							 }
						 }
					 }
				 }
			 }
			 
		 }
	}
	write(ans_time[n][m],1);
}

int main (){
	freopen("cross.in","r",stdin);
	freopen("cross.out","w",stdout);
	read();
}

THE END

标签:int,time,nx,ny,mapp,穿越,ans
来源: https://www.cnblogs.com/LQX-OI/p/16398608.html