https://www.codechef.com/ZCOPRAC/problems/ZCO13004 似乎交不了题目了,所以没法验证对错,但是同标程的做法是一样的。
题意:
有一块n*m大小的地图,一个人要从(1,1)走到(n,m),只能往右/往下走。但是路上会有很多怪物,这些怪物的位置是B(见下图),第i个怪物从ci时间开始活动,有一个周期di,它在这段时间内的运动轨迹如下图P(a=3,b=2,c=1,d=3)。人不能碰到P,求能否安全到达终点。
t=0 t=1 t=2 t=3
S . . . . S . . . . S . . P . S
. . . . . . . . . P . . . . . .
. B . . . P . . P B P . . B . P
. . . . . . . . . P . . . . . .
t=4 t=5 t=6
. . . . . . . . . P . .
. . . S . P . . . . . .
. P . . P B P S . B . P
. . . . . P . . . . . S
Sample Input 1
4 4 1 3 2 1 3
Sample Output 1
YES 6
Sample Input 2
5 5 2 5 1 1 2 4 4 1 2
Sample Output 2
YES 8
Test data
-
2 ≤ N,M ≤ 2500.
乍一看好像是一道很难搞的题目,但是由于只能往右/往下走,所以假如到达某个点(i,j),那么到达时间一定是固定的(i+j-2)。所以只要怪物运动到某点的时间有一次和人到达该点的时间(固定值)重合,那么就不能走这个点啦!
最后再随便dp一下就行了。
#include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
#include<stack>
#include<string.h>
#include<stdlib.h>
#include<cstdio>
#define ll long long
using namespace std;
int x[2505][2505];
int dp[2505][2505];
int main(){
int n,m,k,a,b,c,d;
cin>>n>>m>>k;
for(int i=0;i<k;++i){
cin>>a>>b>>c>>d;
int p=c;
for(int j=a;j<=min(a+d-1,n);++j){ //向下找
if(j+b-2>=p&&(j+b-2)%p==0)
x[j][b]=1;
}
p=c;
for(int j=b;j<=min(b+d-1,m);++j){ //向右找
if(a+j-2>=p&&(a+j-2)%p==0)
x[a][j]=1;
}
p=c;
for(int j=a;j>=max(a-d+1,1);--j){ //向上找
if(j+b-2>=p&&(j+b-2)%p==0)
x[j][b]=1;
}
p=c;
for(int j=b;j>=max(b-d+1,1);--j){ //向左找
if(a+j-2>=p&&(a+j-2)%p==0)
x[a][j]=1;
}
}
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
if(i==1&&j==1)
dp[i][j]=1;
if(dp[i-1][j]==1||dp[i][j-1]==1)
dp[i][j]=1;
}
}
if(dp[n][m]==1)
cout<<"YES"<<endl<<n+m-2<<endl;
else
cout<<"NO"<<endl;
return 0;
}