SCOI2005-扫雷MINE
题目链接:https://ac.nowcoder.com/acm/problem/20241
参考题解链接:https://ac.nowcoder.com/acm/contest/view-submission?submissionId=46536554
题意:不好懂,详见原题,不再复述。
思路:经过最多只有两种情况会满足条件,1:第一个格子不放雷,2:a[0]=1时存在第一个各自放雷情况,分别对两种情况进行模拟,其中当a[i-1]=1时,i位置必须放雷来满足这个条件。
坑点:如果通过计算数组和是否为0来判断是否满足条件是不合理的,测试数据中存在数组和为0但是数组并不全为0的不合法情况。
反思:编码习惯要养成,看了别人的题解,我的编码习惯还是太暴力了
参考上述题解代码后写的:妙啊
(我们变量命名习惯差不多哎)
#include<iostream>
using namespace std;
int a[(int)1e4+5]={0};
int b[(int)1e4+5]={0};
int n;
bool check(int x){
b[1]=x;
for(int i=2;i<=n;i++){
b[i]=a[i-1]-b[i-1]-b[i-2];//规律:当前位置b[i]已经是可以确定的
if(b[i]<0||b[i]>1)return false;//通过对当前b[i]位置被确定的结果进行判断来判断当前排序是否合理。
}
return a[n]==b[n]+b[n-1];//a[n]没有判断,增加特判
}
int main (){
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
int ans=0;
if(check(0))ans++;
if(check(1))ans++;
cout<<ans<<endl;
return 0;
}
我通过的代码:
#include<iostream>
using namespace std;
int a[(int)1e4+5]={0};
int b[(int)1e4+5]={0};
int main (){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
b[i]=a[i];
}
int ans=0;
int all=0,bll=0;
//1:没雷
for(int i=2;i<=n-1;i++){
if(a[i-1]>=1){//i放雷
a[i-1]--;
a[i]--;
a[i+1]--;
}
}
if(a[n-1]>=1){
a[n-1]--;
a[n]--;
}
bool f=true;
for(int i=1;i<=n;i++)if(a[i]!=0)f=false;
if(f)ans++;
// 1:放雷
if(b[1]){
b[1]--;
b[2]--;
for(int i=2;i<=n-1;i++){
if(b[i-1]>=1){
b[i-1]--;
b[i]--;
b[i+1]--;
}
}
if(b[n-1]){
b[n-1]--;
b[n]--;
}
f=true;
for(int i=1;i<=n;i++)if(b[i]!=0)f=false;
if(f)ans++;
}
cout<<ans<<endl;
return 0;
}
由于坑点(编码习惯奇怪导致只能过9个测试数据)的代码
#include<iostream>
using namespace std;
int a[(int)1e4+5]={0};
int b[(int)1e4+5]={0};
int main (){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
b[i]=a[i];
}
int ans=0;
int all=0,bll=0;
//1:没雷
for(int i=2;i<=n-1;i++){
if(a[i-1]>=1){//i放雷
a[i-1]--;
a[i]--;
a[i+1]--;
}
}
if(a[n-1]>=1){
a[n-1]--;
a[n]--;
}
for(int i=1;i<=n;i++)all+=a[i];
if(all==0)ans++;
// 1:放雷
if(b[1]){
b[1]--;
b[2]--;
for(int i=2;i<=n-1;i++){
if(b[i-1]>=1){
b[i-1]--;
b[i]--;
b[i+1]--;
}
}
if(b[n-1]){
b[n-1]--;
b[n]--;
}
for(int i=1;i<=n;i++)bll+=b[i];
if(bll==0)ans++;
}
cout<<ans<<endl;
return 0;
}

浙公网安备 33010602011771号