hiho刷题日记——第三十天小Hi小Ho的惊天大作战:扫雷·一

题目

简化版扫雷,只有一行。
给出一行的周围3格中是雷的数量。
判断哪些一定是雷,一定不是雷。
这里写图片描述

思路

因为给出的信息是环环相扣的,不用一个一个去试。
只需要试第一格是否为雷就可以通过数据算出后面是否为雷。
所以只用试两次,
第一次把一格设为雷,算出后面的情况;第二次把第一格设为不是雷,算出后面的情况。
若两次都算出来了,则将两次的情况对比,没有变化的部分就是答案。
若只有一次满足条件,则那一次直接就是答案。

代码

#include<cstdio>
#include<cstring>
using namespace std;

const int MAXN=100000+2;
int N,M,a[MAXN],ans[2][MAXN],count[]={0,0},stat1[MAXN],stat2[MAXN];
int t1,t2;

bool run(int flag,int *s)
{
  s[0]=0;
  s[1]=flag;
  for(int i=1;i<N;i++)
  {
    s[i+1]=a[i]-s[i]-s[i-1];
    if(s[i+1]!=0 && s[i+1]!=1) return false;
  }
  if(a[N]==s[N-1]+s[N]) return true;
  return false;
}

int main()
{
  scanf("%d",&M);
  a[0]=0;
  while(M--)
  {
    t1=t2=count[0]=count[1]=0;

    scanf("%d",&N);
    for(int i=1;i<=N;i++) scanf("%d",&a[i]);

    if(run(0,stat1)) t1=1;
    if(run(1,stat2)) t2=1;
    if(t1)
    {
      if(t2)
      {
        for(int i=1;i<=N;i++)
        if(stat1[i]==stat2[i]) ans[stat1[i]][count[stat1[i]]++]=i;
      }
      else
      {
        for(int i=1;i<=N;i++)
        ans[stat1[i]][count[stat1[i]]++]=i;
      }
    }
    else if(t2)
    {
      for(int i=1;i<=N;i++)
      ans[stat2[i]][count[stat2[i]]++]=i;
    }

    printf("%d",count[1]);
    if(count[1])
    {
        for(int i=0;i<count[1];i++) printf(" %d",ans[1][i]);
    }
    printf("\n");
    printf("%d",count[0]);
    if(count[0])
    {
        for(int i=0;i<count[0];i++) printf(" %d",ans[0][i]);
    }
    printf("\n");
  }
  return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值