穿越

题目描述

解析

纯搜索,dp。

每次四个方向以及所有传送门,还可以不走,判断 \(rain\) 最早下的时间,判雨,判兽;

code
#include<bits/stdc++.h>
#define se second
#define fi first
using namespace std;
const int N = 305;
int n,m,mp[N][N],a,b,rain[N][N];
bool dp[10000][N][N];
int cnt,ans=10000;
pair<int,int> csm[N*N];
vector<pair<int,int> > shou[N][N];
int xx[5]={-1,0,1,0,0},yy[5]={0,-1,0,1,0};
bool safe(int x,int y,int t)
{
	if(mp[x][y]==1) return 0;
	if(rain[x][y]<=t) return 0;
	if(mp[x][y]==2)
		for(pair<int,int> s:shou[x][y]) 
			if(t>=s.fi&&t<=s.se) return 0;
	return 1;
}
int main()
{
	freopen("cross.in","r",stdin);
	freopen("cross.out","w",stdout);
	memset(rain,0x3f,sizeof rain);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			scanf("%d",&mp[i][j]);
			if(mp[i][j]==3) csm[++cnt]=make_pair(i,j);
		}
	}
	scanf("%d",&a);
	for(int i=1;i<=a;i++)
	{
		int t; scanf("%d",&t);
		int p; scanf("%d",&p);
		for(int j=1;j<=p;j++)
		{
			int x,y; scanf("%d%d",&x,&y);
			rain[x][y]=min(rain[x][y],t);
		}
	}
	scanf("%d",&b);
	for(int i=1;i<=b;i++)
	{
		int t1,t2;  scanf("%d%d",&t1,&t2);
		int x,y; scanf("%d%d",&x,&y);
		shou[x][y].push_back(make_pair(t1,t2));
	}
	dp[0][1][1]=1;
	for(int t=0;t<=10000;t++)
	{
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=m;j++)
			{
				if(!dp[t][i][j]) continue;
				if(i==n&&j==m) printf("%d\n",t),exit(0);
				for(int d=0;d<5;d++)
				{
					int x=i+xx[d],y=j+yy[d];
					if(safe(x,y,t+1)) dp[t+1][x][y]=1;
				}
				if(mp[i][j]==3)
				{
					for(int k=1;k<=cnt;k++)
					{
						int x=csm[k].fi,y=csm[k].se;
						if(x==i&&y==j) continue;
						if(safe(x,y,t+2)) dp[t+2][x][y]=1;
					}
				}
			}
		}
	}
	return 0;
}

注意

码力有待提升,赛时唐氏 \(dfs\) ,数据再水也得 \(\mathbb{T}\)

能用dp就用dp,开三维,遍历时间(复杂度肯定超,但水)。

P.S.

已改,误 \(\mathbb{D}\) .

posted @ 2024-05-14 21:28  ppllxx_9G  阅读(67)  评论(6)    收藏  举报