题目链接: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<B
A<C
B<D
输入
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肯定不行,若c<d,那肯定b先到d,然后a再到c,判断是否可以成立,若c>d,先看看像第二种方法能不能跑过去,如果不能的话,那就看看,中途a能不能超车,超车的条件是有至少连续三个空地。
#include<bits/stdc++.h>
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;
}