hiho_1114_扫雷

http://hihocoder.com/problemset/problem/1114

这道题,扫雷,两行,给出第二行全部的地雷数目,让我们猜测第一行。

思路:

考虑扫雷第二行数字的意义,(已知)[2][i]=[1][i-1]+[1][i]+[1][i+1]

     第二行是从1开始的,我们将第一行第[0]列当作是0,没有地雷,如果[1]确定了,那么[2]也确定了,[3].... 完美解决~

[1][0]=0 ,  [1][1]= 0/1/确定,[1][2] = [2][1] - [1][0] - [1][1]

1、所以是枚举的问题,[1] 有两种可能0/1,所以枚举很简单。但是,扫雷是那么随便填的吗?!/反正是一把心酸泪被炸过来的/ 所以在枚举过程中可能会遇到某个格子填的数字是-1,比如

0 0 2
0 2  
0 1 -1
1 0  

2、正常情况下[i]=0/1,所以每填一个数字都要检查一下,如果不是0/1,则弄个标志处理,表示当前第一个填0/1这种情况是不可取的。

3、瞧,上面的右下角都有一个空缺,难不成第二行最后一个没用的么,当然不是,我们还要检测[2][n]==[1][n-1]+[1][n]是否符合,因为在填[1][n]和[1][n-1]时是根据[2][n-1]和[2][n-1]填的,并没有考虑到[2][n],所以要检测。

tips:由于第一行最左边和最右边可以假想为没有炸弹,所以可以加上[0][n+1],在写迷宫类型的,也可以参照这种方式,在周边加上一个围栏好处:有些判断的情况上方便,不怕溢出,如 for循环[i-1] 不会越界,或者[i-1]=0的会使用时不会非法访问内存。瞎扯:在数学几何上的辅助线,一座通往光明的桥梁!小说里想象它们是小精灵来帮助我们~喵~

AC代码:

#include <iostream>
#include <vector>
#include<cstdio>
using namespace std;
int know[100010],a[2][100010];
int main()
{
    int T,n;
    cin >> T;
    while(T--){
        cin >> n;
        for(int i=1;i<=n;++i) scanf("%d",&know[i]);
        for(int first=0;first<2;++first){   // first 表示第一格子填的值是first,为0/1
            a[first][0]=a[first][n+1]=0;    // 假象的第0个或者第n+1个格子
            a[first][1]=first;          // 填第1个格子
            for(int i=2;i<=n+1;++i){       // 填2-n个格子,注意要填n+1格子主要是为了检测第二行第n个数字
                a[first][i]=know[i-1]-a[first][i-1]-a[first][i-2]; // 填!
                if(a[first][i]!=0&&a[first][i]!=1) {          // 检查
                    a[first][n+1]=1;
                    break;
                }
            }
            if(a[first][n+1]!=0) // 如果这种情况不可取,那么把全部格子填成不是0/1的数字表示不可达的情况
                for(int i=1;i<=n;++i) a[first][i]=-1;
        }

        int bomb=0,nobomb=0;
        for(int i=1;i<=n;++i){
            if(a[0][i]!=0&&a[1][i]!=0) bomb++;
            if(a[0][i]!=1&&a[1][i]!=1) nobomb++;
        }

/*        for(int i=1;i<=n;++i)
            cout << a[0][i] <<" " ;
        cout << endl;
        for(int i=1;i<=n;++i)
            cout << a[1][i] <<" " ;
        cout << endl;
*/

        cout << bomb ;
        for(int i=1;i<=n;++i)
            if(a[0][i]!=0&&a[1][i]!=0) cout << " " << i ; // 如果a[0][]或a[1][]是错的,那么只会考虑到另一种情况,!=0是不会影响的。。。
        cout << endl;

        cout << nobomb;
        for(int i=1;i<=n;++i)
            if(a[0][i]!=1&&a[1][i]!=1) cout << " " << i ;
        cout << endl;
    }
    return 0;
}
时间: 2024-12-24 12:01:22

hiho_1114_扫雷的相关文章

bzoj1088[SCOI2005]扫雷

bzoj1088[SCOI2005]扫雷 题意: 有一个n×2的棋盘,第一列里面某些格子是雷,而第二列没有雷.由于第一列的雷可能有多种方案满足第二列的信息的限制,求根据第二列的信息第一列雷有多少种摆放方案. 题解: 水题,因为每个第一行的格子可以根据前一个第二行的格子里的信息唯一确定是否有雷,所以只要枚举第一个格子有没有雷就行. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #

洛谷P2670 扫雷游戏

题目描述 扫雷游戏是一款十分经典的单机小游戏.在n行m列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格).玩家翻开一个非地雷格时,该格将会出现一个数字--提示周围格子中有多少个是地雷格.游戏的目标是在不翻出任何地雷格的条件下,找出所有的非地雷格. 现在给出n行m列的雷区中的地雷分布,要求计算出每个非地雷格周围的地雷格数. 注:一个格子的周围格子包括其上.下.左.右.左上.右上.左下.右下八个方向上与之直接相邻的格子. 输入输出格式 输入格式: 输入文件第一行是用一个

Vijos 1193 扫雷 【动态规划】

扫雷 描述 相信大家都玩过扫雷的游戏.那是在一个n*n的矩阵里面有一些雷,要你根据一些信息找出雷来.万圣节到了,"余"任过流行起了一种简单的扫雷游戏,这个游戏规则和扫雷一样,如果某个格子没有雷,那么它里面的数字表示和他8连通的格子里面雷的数目.现在棋盘是n*2的,第一列里某些格子是雷,而第二列没有雷,如:o 1* 2* 3* 2o 2* 2* 2 ('*'代表有雷,'o'代表无雷)由于第一类的雷有可能有多种方案满足第二列的数的限制,你的任务即根据第二列的信息求第一列雷有多少中摆放方案.

扫雷C++实现

1 #include <iostream> 2 #include<fstream> 3 #include <ctime> 4 #include <cmath> 5 #include <stdlib.h> 6 #include<stdio.h> //时间 //文件 7 #include <string> 8 #define random(x)(rand()%x) 9 using namespace std; 10 void

VB一键扫雷

XP游戏,扫描内存,然后模拟鼠标点击 Private Sub Command1_Click() Dim lhwnd As Long Dim lpid As Long Dim lRet As Long Dim lhProcess As Long Dim bData(1024) As Byte Dim bXY(8) As Byte Dim x As Long Dim y As Long Dim temp As Long Dim k As Long '其中8F就表示雷,0F表示非雷,当非雷区被点击后如

BZOJ1088 [SCOI2005]扫雷Mine

Description 相信大家都玩过扫雷的游戏.那是在一个n*m的矩阵里面有一些雷,要你根据一些信息找出雷来.万圣节到了 ,“余”人国流行起了一种简单的扫雷游戏,这个游戏规则和扫雷一样,如果某个格子没有雷,那么它里面的数字 表示和它8连通的格子里面雷的数目.现在棋盘是n×2的,第一列里面某些格子是雷,而第二列没有雷,如下图: 由于第一列的雷可能有多种方案满足第二列的数的限制,你的任务即根据第二列的信息确定第一列雷有多少种摆放 方案. Input 第一行为N,第二行有N个数,依次为第二列的格子中

Delphi - XP扫雷外挂制作

技术交流,DH讲解. 本来之前就在写这个文章,还写了War3挂的教程,后来因为一些事就没有弄了.现在过年在家又没有事就继续把这个写完吧.哈哈.不要以为写个挂很容易,要想写个挂肯定要了解游戏呀.我们现在来了解下地雷是怎么产生的?其实只是我自己猜想的,毕竟这个游戏不是我写的...1 用户选择了多大的棋盘,多少地雷后棋盘应该是用一个二维数组来存储的,地雷数肯定是用一个全局变量来存储的.这点儿有异议没有?没有我就继续往下说了...2 生成地雷,肯定是随机的,那么一定会调用Rand函数咯.a.首先判断地雷

c++ 控制台版 扫雷游戏

白天看了一天书看累了,晚上瞅见扫雷游戏,就自己琢磨着做一个呗.想了一会,也没看别人怎么做的,大概1个多小时完成了这个简单版本的扫雷游戏,由于没怎么学过c#,界面的事情可能迟几天再做,明天要回家啦,哈哈! 先说思路,其实挺简单的. (1) 随机生成10个雷,标记到二维数组里,然后计算八个方向的雷的总数记录下来,这是预处理阶段. (2)输入要翻开的位置的坐标,如果是数字直接显示,是空白的话,这里采用bfs即宽度优先搜索解决,搜到最外层是数字(仅一层)时结束,具体详见代码. // 扫雷程序 #incl

迟到的儿童节礼物——小游戏三件套:扫雷,俄罗斯方块,数独

人的事情要么是饿出来了要么就是吃饱了撑出来的 其实写完刚好是在儿童节前两天,本打算作为儿童节礼物送给大家,结果新账号要3天才能发文章到主页,于是拖到了现在...事情是这样开始的:有一天,闲得蛋疼,看见同事在玩扫雷,然后就想着自己做一个,于是花了三天时间写一个自己的扫雷...写完扫雷感觉不过瘾,于是接着又写了俄罗斯方块,一晃又是三天...写完俄罗斯方块之后,觉得事不过三,再来一个,然后选了数独,其实知道这个应该是最有难度的,果然也纠结了三天数独生成算法才勉强写完...好了废话不多说,上图. 1.