Gym - 102021L Logic Puzzle 【思维】


传送门:Logic Puzzle


Problem L: Logic Puzzle

While browsing a kiosk at a recent trip, you bought a magazine filled with various kinds of logic
puzzles. After a while of solving, however, you start to get a bit bored of the puzzles. Still
wanting to complete all the puzzles in the magazine, you start wondering about ways to solve
some of them algorithmically.
The puzzle you are currently trying to solve is called Mosaic, and it is quite similar to the classic
Minesweeper video game:
在这里插入图片描述
You are given a two-dimensional grid of cells, initially all white, and you have to color some of
the cells in black. You are also given a grid of clue numbers, which extends beyond the borders
of the puzzle grid by one cell in each direction. The number in a cell indicates (exactly) how
many cells in the 3 × 3 block centered at this cell need to be colored in black. You may not color
any cells outside of the original grid

Input
The input consists of:
• one line with two integers h, w (1 ≤ h, w ≤ 100), the height and width of the puzzle;
• h + 2 lines, each with w + 2 integers c1, . . . , cw+2 (0 ≤ ci ≤ 9), the clue numbers.

Output
If the given clue numbers are inconsistent, output impossible. Otherwise, output h lines
with w characters each, the solution to the puzzle. Use X for black cells and . for white cells. If
there are multiple solutions, any of them will be accepted.

Sample Input 1
2 3
1 1 2 1 1
1 2 3 2 1
1 2 3 2 1
0 1 1 1 0
Sample Output 1
X.X
.X.

Sample Input 2
1 2
0 0 1 1
0 1 1 1
0 1 1 1
Sample Output 2
impossible



题意:
扫雷游戏。给你一个二维网格,中间的网格为我们要判断的雷区,每个单元格表示其周围一圈(包括自己)的炸弹的数目。如果能确定就输出,不能确定输出impossible


题解:
一行一行判断,首先判断第一个,如果他的左上角不为0,就说明他应该是炸弹,同时更新左上角周围一圈的数字,都减1,接着判断下一个。
当全部判断完后,看这个数组里的数是否都是0,如果是则说明解合法,不是则说明不合法。



AC代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int N=1100;
int a[N][N];
int vis[N][N];
int h,w;
void update(int x,int y)//更新数组
{
  for(int i=x-1;i<=x+1;i++)
  {
    for(int j=y-1;j<=y+1;j++)
    {
      a[i][j]--;
    }
  }
}
int main()
{
  scanf("%d%d",&h,&w);
  for(int i=0;i<=h+1;i++)
  {
    for(int j=0;j<=w+1;j++)
    {
      scanf("%d",&a[i][j]);
    }
  }
  for(int i=1;i<=h;i++)
  {
    for(int j=1;j<=w;j++)
    {
      if(a[i-1][j-1]!=0)
      {
        update(i,j);
        vis[i][j]=1;//标记为炸弹
      }
    }
  }
  int flag=0;//判断解是否合法
  for(int i=0;i<=h+1;i++)
  {
    for(int j=0;j<=w+1;j++)
    {
      if(a[i][j]!=0)
      {
        flag=1;
        break;
      }
    }
  }
  if(flag) printf("impossible\n");
  else
  {
    for(int i=1;i<=h;i++)
    {
      for(int j=1;j<=w;j++)
      {
        if(vis[i][j])
          printf("X");
        else
          printf(".");
      }
      printf("\n");
    }
  }
  return 0;
}

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值