中石油新生第一次训练赛 H题扫雷

时间限制: 1 Sec 内存限制: 128 MB
提交: 187 解决: 32

题目描述

小Q空的时候挺喜欢玩玩电脑游戏的。自从编程技术提高后,他就想,要是自己也能开发出一款游戏来,那该多好啊!不过,小Q也不着急,先练好基本功再说。Windows中就有一款叫扫雷的小游戏,挺好玩的,不过想编出一个来,还真不容易。小Q就自己设想了一种简单的扫雷游戏:在n行2列的方格棋盘上,左列某些方格内埋有地雷,而右列每个方格中都有一个数字(0~3),第I格的数字表示:左列第I-1、I、I+1格(即:上、中、下三格)中埋雷的总数。如下所示:左图是初始状态,右图是扫雷完成状态(插小旗的方格内有雷)。

你的任务是:根据右列的数字分析出左列格子中的地雷(0表示无雷,1表示有雷),并且统计出左列格子中地雷的总数。
小Q想,如果这样的任务能完成了,相信编出更复杂的扫雷游戏也就为期不远了。

输入

第一行,一个整数N(2≤N≤40),第二行有N个数字(以一个空格相隔),表示右列格子中的数字。输入数据保证正确有解。

输出

第一行是N个0、1数字(没有空格相隔),表示左列每格中有无地雷。第二行一个整数,表示地雷总数。
样例输入
7
1 2 3 2 2 2 2

样例输出
0111011
5

这个题当时就差一点点就做出来了,只少了一句

if(a[0][1]==0)
	mark=1;

我的做法也没有什么技巧,就是利用一个小规律。
在这里插入图片描述
只要我能确定出第一个格子有没有雷,题目其实就已经解决了。第一个格子无非两种情况,有雷or无雷,这样就可以先假设第一个格子有雷,这样根据a【0】【1】的值就可以确定第二个有没有雷,然后后面的就都出来了,在推出后面的时候如果出现矛盾,则假设是错的,转而让第一个格子没有雷,在进行一次推理就可以了。
昨天错在哪了呢,如果输入的a【0】【1】为0,在数据少于3个时 我先假设有雷的话会默认第一个有雷(由于数据较少不会进入循环,无法判断是否矛盾),这和a【0】【1】为0是互相矛盾的,但是我没有去判断这个矛盾,导致出错。所以加上上面那一句,判断一下就好了。(找了好久。。。。)

#include <stdio.h>
int main()
{
	int n;
	int a[40][2];
	int mark=0;
	int cnt;
	int x=0;
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		scanf("%d",&a[i][1]);a[i][0]=0;
	}
	if(a[0][1]==0)
	mark=1; //判断一下前两个格没有雷的情况,以免数据少时出错
	else
	{
		a[0][0]=1; //假设第一格有雷
		if(a[0][1]==2)  //推第二格
		a[1][0]=1;
		else
		a[1][0]=0;
	}
	for(int i=1;i<n-1;i++)
	{
		cnt=0;
		for(int j=i-1;j<=i;j++)
		if(a[j][0]==1)
		cnt++;
		if(a[i][1]-cnt==1)
		a[i+1][0]=1;  //推出后面
		else if((cnt+1)<a[i][1])    //这里是矛盾判断,如果雷数+1还比总雷数小,那假设第一个有雷这种情况就不对了 ,做个标记,退出循环。
		{
			for(int k=0;k<n;k++) a[k][0]=0;
			mark=1;break;
		}
	}
	if(mark==1) //如果第一格有雷不成立
	{
		a[0][0]=0;
		if(a[0][1]==1)
		a[1][0]=1;
		else
		a[1][0]=0;
		for(int i=1;i<n-1;i++)
		{
			cnt=0;
			for(int j=i-1;j<=i;j++)
				if(a[j][0]==1)
				cnt++;
		if(a[i][1]-cnt==1)
		a[i+1][0]=1;
		}
	}
	for(int i=0;i<n;i++)
	{
		printf("%d",a[i][0]);if(a[i][0]==1) x++; 
	}
	printf("\n");
	printf("%d",x);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43332389/article/details/84754746
今日推荐