【codechef】Save Spaceman Spiff(人能否安全从起点走到终点)

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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值