逻辑推理题。根据扫雷经验可以知道,边界上的格子一定是本题的突破口。先看第一列前两个格子,它们对应的是第二列的第一个格子,我们设之为(a_1)。如果(a_1=0)或(a_1=2),则第一列前两个格子的方案唯一确定,所以我们只需判断输入是否合法即可。如果(a_1=1),我们就枚举哪一个格子是有雷的,判断一下即可。
// BZOJ 1088
#include <cstdio>
using namespace std;
const int N=10000+5;
#define read(x) scanf("%d", &x)
#define rep(i,a,b) for (int i=a; i<=b; i++)
int a[N], b[N], n;
int judge() {
for (int i=3; i<=n; i++) {
b[i]=a[i-1]-b[i-1]-b[i-2];
if (b[i]>1 || b[i]<0) return 0;
}
if (a[n]!=b[n-1]+b[n]) return 0; // 别忘了a[n]这个边界!
return 1;
}
int main()
{
read(n);
rep(i,1,n) read(a[i]);
int ans;
if (a[1]==0) { b[1]=b[2]=0; ans=judge(); }
else if (a[1]==2) { b[1]=b[2]=1; ans=judge(); }
else {
b[1]=1; b[2]=0; ans=judge();
b[1]=0; b[2]=1; ans+=judge();
}
printf("%d
", ans);
return 0;
}