P7660 [COCI2014-2015#5] ZMIJA 题解
思路:
对于第 i 行,如果本行的所有的苹果都吃完了,那么有以下几种情况:
- 若本行往左走,则现在的列下标必须大于等于上一行最左边的苹果的列下标。
- 若本行往右走,则现在的列下标必须小于等于上一行最右边的苹果的列下标。
如果满足以上任意一条,则就可以走到上一行。
if(f == 1 && y >= fr[x-1] && Sum >= J[x]) {
if(dfs(x-1, y, 2, 1) == false)
return false;
} else if(f == 2 && y <= fl[x-1] && Sum >= J[x]) {
if(dfs(x-1, y, 1, 1) == false)
return false;
}
如果一条都不满足,则该往左走往左走,该往右走往右走。
if(f == 1) {
if(dfs(x, y+1, f, 0) == false)
return false;
} else {
if(dfs(x, y-1, f, 0) == false)
return false;
}
注意:
为了方便我们将 dfs 定义成 bool 类型,如果吃完了最后一个苹果就返回 false。
代码:
#include <bits/stdc++.h>
using namespace std;
int n, m, cnt, sum, eat, Sum;
char mp[1010][1010];
int fr[1010], fl[1010], J[1010];
//fr[i]:表示第i行最右边的J的位置
//fl[i]:表示第i行最左边的J的位置
//J[i]:表示第i行J的数量
//F:是否要更新Sum
//Sum:本行出现‘J’的个数
//f:方向,1向右,2向左
//x、y:所在的行和列
bool dfs(int x, int y, int f, int F) {
if(F == 1)
Sum = 0;
if(mp[x][y] == 'J')
eat++, Sum++;
if(eat == sum)
return false;
cnt++;
if(f == 1 && y >= fr[x-1] && Sum >= J[x]) {
if(dfs(x-1, y, 2, 1) == false)
return false;
} else if(f == 2 && y <= fl[x-1] && Sum >= J[x]) {
if(dfs(x-1, y, 1, 1) == false)
return false;
} else{
if(f == 1) {
if(dfs(x, y+1, f, 0) == false)
return false;
} else {
if(dfs(x, y-1, f, 0) == false)
return false;
}
}
return true;
}
int main() {
cin >> n >> m;
memset(fl, 0x3F, sizeof(fl));
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++) {
cin >> mp[i][j];
if(mp[i][j] == 'J'){
J[i]++;
fr[i] = j;
fl[i] = min(fl[i], j);
sum++;
}
}
dfs(n, 1, 1, 1);
cout << cnt;
return 0;
}
本文来自博客园,作者:Simba秋,转载请注明原文链接:https://www.cnblogs.com/yangzichen/p/16897416.html

浙公网安备 33010602011771号