Contest1786 - 2019年第二阶段我要变强个人训练赛第十场 问题 A: Kenken Race dp超车

题目链接:http://icpc.upc.edu.cn/problem.php?cid=1786&pid=0

题目描述

There are N squares arranged in a row, numbered 1,2,...,N from left to right. You are given a string S of length N consisting of . and #. If the i-th character of S is #, Square i contains a rock; if the i-th character of S is ., Square i is empty.
In the beginning, Snuke stands on Square A, and Fnuke stands on Square B.
You can repeat the following operation any number of times:
Choose Snuke or Fnuke, and make him jump one or two squares to the right. The destination must be one of the squares, and it must not contain a rock or the other person.
You want to repeat this operation so that Snuke will stand on Square C and Fnuke will stand on Square D.
Determine whether this is possible.

Constraints
4≤N≤200000
S is a string of length N consisting of . and #.
1≤A,B,C,D≤N
Square A, B, C and D do not contain a rock.
A, B, C and D are all different.
A A B

 

输入

Input is given from Standard Input in the following format:

N A B C D
S

 

 

输出

Print Yes if the objective is achievable, and No if it is not.

 

样例输入

复制样例数据

7 1 3 6 7
.#..#..

样例输出

Yes

题解: 若c==d肯定不行,若cd,先看看像第二种方法能不能跑过去,如果不能的话,那就看看,中途a能不能超车,超车的条件是有至少连续三个空地。

#include

using namespace std;

typedef long long ll;
const int N = 200100;

char s[N];
int dp[N];
int n;
int a, b, c, d;
int main() {

	while(~scanf("%d %d %d %d %d", &n, &a, &b, &c, &d)) {
		scanf("%s", s + 1);
		if( c == d ) {
			printf("No\n");
			continue;
		}
		for(int i = 0; i <= n; i++) dp[i] = 0;
		if(c < d) {
			dp[b] = 1;
			for(int i = b + 1; i <= d; i++) {
				if(s[i] == '#' ) continue;
				dp[i] = dp[i - 1] | dp[i - 2];
			}
			if(!dp[d]) {
				printf("No\n");
				continue;
			}
			for(int i = 0; i <= n; i++) dp[i] = 0;
			dp[a] = 1;
			for(int i = a + 1; i <= c; i++) {
				if(s[i] == '#' || i == d) continue;
				dp[i] = dp[i - 1] | dp[i - 2];
			}
			if(!dp[c]) {
				printf("No\n");
				continue;
			}
			printf("Yes\n");
		} else {
			dp[b] = 1;
			for(int i = b + 1; i <= d; i++) {
				if(s[i] == '#' ) continue;
				dp[i] = dp[i - 1] | dp[i - 2];
			}
			if(!dp[d]) {
				printf("No\n");
				continue;
			}
			for(int i = 0; i <= n; i++) dp[i] = 0;
			dp[a] = 1;
			for(int i = a + 1; i <= c; i++) {
				if(s[i] == '#' || i == d) continue;
				dp[i] = dp[i - 1] | dp[i - 2];
			}
			if(dp[c]) {
				printf("Yes\n");
				continue;
			}
			for(int i = 0; i <= n; i++) dp[i] = 0;
			dp[a] = 1;
			for(int i = a + 1; i <= c; i++) {
				if(s[i] == '#' ) continue;
				dp[i] = dp[i - 1] | dp[i - 2];
			}
			int flag = 0;
			for(int i = b - 1; i <= d- 2; i++) {
				if(s[i] == '.' && s[i + 1] == '.' && s[i + 2] == '.')
					flag = 1; 
			}
			printf(dp[c] && flag ? "Yes\n" : "No\n");
		}
		
	}

	return 0;
}

 

你可能感兴趣的:(思维,dp)