[BFS,大水题] Codeforces 198B Jumping on Walls
题目:http://codeforces.com/problemset/problem/198/B
Vasya plays a computer game with ninjas. At this stage Vasya's ninja should get out of a deep canyon.
The canyon consists of two vertical parallel walls, their height is n meters. Let's imagine that we split these walls into 1 meter-long areas and number them with positive integers from 1 to n from bottom to top. Some areas are safe and the ninja can climb them. Others are spiky and ninja can't be there. Let's call such areas dangerous.
Initially the ninja is on the lower area of the left wall. He can use each second to perform one of the following actions:
- climb one area up;
- climb one area down;
- jump to the opposite wall. That gets the ninja to the area that is exactly k meters higher than the area he jumped from. More formally, if before the jump the ninja is located at area x of one wall, then after the jump he is located at area x + k of the other wall.
If at some point of time the ninja tries to get to an area with a number larger than n, then we can assume that the ninja got out of the canyon.
The canyon gets flooded and each second the water level raises one meter. Initially the water level is at the lower border of the first area. Ninja cannot be on the area covered by water. We can assume that the ninja and the water "move in turns" — first the ninja performs some action, then the water raises for one meter, then the ninja performs one more action and so on.
The level is considered completed if the ninja manages to get out of the canyon.
After several failed attempts Vasya started to doubt whether it is possible to complete the level at all. Help him answer the question.
The first line contains two integers n and k (1 ≤ n, k ≤ 105) — the height of the canyon and the height of ninja's jump, correspondingly.
The second line contains the description of the left wall — a string with the length of ncharacters. The i-th character represents the state of the i-th wall area: character "X" represents a dangerous area and character "-" represents a safe area.
The third line describes the right wall in the same format.
It is guaranteed that the first area of the left wall is not dangerous.
Print "YES" (without the quotes) if the ninja can get out from the canyon, otherwise, print "NO" (without the quotes).
7 3
---X--X
-X--XX-
YES
6 2
--X-X-
X--XX-
NO
In the first sample the ninja should first jump to the right wall, then go one meter down along the right wall, then jump to the left wall. The next jump can get the ninja from the canyon.
In the second sample there's no way the ninja can get out of the canyon.
题意:
有一个人在两堵平行的墙之间,每面墙墙被分为n个单位,墙上有一些位置人不能到达,人可以移动,但每次移动水位会上升,人不能碰到水,现在初始位置在左边最下方,就是样例中的左上角,若人当前高度为x,则人每次可以进行三种操作,
第一种是在当前墙上升一个单位即x+1,第二种是在当前墙下降一个单位及x-1,第三种是跳的另一个墙上且高度变为x+k,问人能否跳出墙(人的高度严格大于n!!!注意是严格大于,也就是不能等于)且不被水淹没
思路:
一道非常水的搜索大水题,真想吐槽一下赛时没把问题想明白,在比赛时写成了判断条件写出了y+k>=n,但有可能k==1导致跳了一格后水正好上升一格,就凉凉,赛后改成y+k>n就AC了,真想给当时的自己一巴掌
by the way,注意人物先移动了水才会上升,所以先判断能不能跳出去再判断水有没有上升到人所在的层
注意:
问人能否跳出墙(人的高度严格大于n!!!注意是严格大于,也就是不能等于)且不被水淹没
人物先移动了水才会上升,所以先判断能不能跳出去再判断水有没有上升到人所在的层
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int amn=1e5+5; 4 #define fi first 5 #define se second 6 int n,k,mp[5][amn],hm[5][amn];bool valid,idx[5][amn]; 7 struct pii{ 8 int first,second,h; 9 pii(int f,int s,int hh){first=f,second=s,h=hh;} 10 }; 11 void bfs(){ 12 memset(idx,0,sizeof idx); 13 queue<pii> q; 14 idx[0][1]=1; 15 q.push(pii(0,1,0)); 16 while(q.size()){ 17 int x=q.front().first,y=q.front().second,h=q.front().h;q.pop(); 18 if(y+k>n){valid=1;return;} ///赛时没把问题想明白,在比赛时写成了判断条件写出了y+k>=n,但有可能k==1导致跳了一格后水正好上升一格,就凉凉,赛后改成y+k>n就AC了,真想给当时的自己一巴掌 19 if(y<=h){continue;} ///这里是先跳了水才会上升,所以先判断能不能跳出去再判断水有没有上升到人所在的层 20 if(!idx[x][y+1]&&mp[x][y+1]){idx[x][y+1]=1;q.push(pii(x,y+1,h+1));} 21 if(!idx[x][y-1]&&mp[x][y-1]){idx[x][y-1]=1;q.push(pii(x,y-1,h+1));} 22 if(!idx[x^1][y+k]&&mp[x^1][y+k]){idx[x^1][y+k]=1;q.push(pii(x^1,y+k,h+1));} 23 } 24 } 25 int main(){ 26 ios::sync_with_stdio(0); 27 cin>>n>>k; 28 char in; 29 for(int i=1;i<=n;i++){ 30 cin>>in; 31 if(in=='-')mp[0][i]=1; 32 else mp[0][i]=0; 33 } 34 for(int i=1;i<=n;i++){ 35 cin>>in; 36 if(in=='-')mp[1][i]=1; 37 else mp[1][i]=0; 38 } 39 valid=0; 40 bfs(); 41 if(valid!=0)printf("YES\n"); 42 else printf("NO\n"); 43 } 44 /** 45 有一个人在两堵平行的墙之间,每面墙墙被分为n个单位,墙上有一些位置人不能到达,人可以移动,但每次移动水位会上升,人不能碰到水,现在初始位置在左边最下方,就是样例中的左上角,若人当前高度为x,则人每次可以进行三种操作, 46 第一种是在当前墙上升一个单位即x+1,第二种是在当前墙下降一个单位及x-1,第三种是跳的另一个墙上且高度变为x+k,问人能否跳出墙(人的高度严格大于n!!!注意是严格大于,也就是不能等于)且不被水淹没 47 一道非常水的搜索大水题,真想吐槽一下赛时没把问题想明白,在比赛时写成了判断条件写出了y+k>=n,但有可能k==1导致跳了一格后水正好上升一格,就凉凉,赛后改成y+k>n就AC了,真想给当时的自己一巴掌 48 by the way,注意人物先移动了水才会上升,所以先判断能不能跳出去再判断水有没有上升到人所在的层 49 **/