穿越
题目描述




解析
纯搜索,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}\) .
浙公网安备 33010602011771号