思路
(其实有点巧,第一次不太好想到):首先,只有判断第一行第一列是否you'lei第二列的某个元素等于第一列中它的同一行及其上下两行的三个元素之和,利用等式的性质,即第i行第一列等于第i-1行第二列-第i-1行第一列-第i-2行第一列,且只能由前面推后面,这里画个图会清晰很多。而又由于第一列的元素只有无雷和有雷(0和1),那么根据上面那个公式计算出来的i行第一列的元素如果不等于0且不等于1,那么就退出矛盾来了(这个思路有点巧,我自己想的时候没想出来如何判断某一行是否不符合右面那一列雷的数量)。 大致思路有了,现在我们来考虑边界的情况: 1.第一行第一列前面没有数,怎么办,难道要单独拎出来写代码吗?然而并不用,我们看作第“-1”行第一列和第“0”行第一列是0就可以了,然而多出两个0并不会对右边的雷数造成影响,0加任何数不改变其大小(这种思想在数学中也很常见)。 2.用第i-1行第二列只能判断第i行第一列是否正确,那么怎么判断雷的情况是否符合最后一行第二列的元素?同样,只需要多算第n+1行第一列的元素再判断是否等于0即可————这里有两种理解,1.是n+1行第二列本来就没有雷,算出来不是0就可以推出矛盾了2.n+1行第一列等于0证明第n-1行第二列-第n-1行第一列-第n-2行第一列==0,符合题目条件。
AC代码:
#include<iostream>
using namespace std;
int a[10010][2]={0};
int main()
{
ios::sync_with_stdio(false);cin.tie(nullptr);
int n;cin>>n;
int res=2;
for(int i=1;i<=n;i++){cin>>a[i][1];}
for(int i=0;i<=1;i++)
{
a[1][0]=i;
for(int i=2;i<=n+1;i++)
{
a[i][0]=a[i-1][1]-a[i-1][0]-a[i-2][0];
if(a[i][0]!=0 && a[i][0]!=1){res--;break;}
}
}
if(a[n+1][0]!=0){res--;} //等于1也不行,故这里要再判断一次
cout<<res;
return 0;
}