//众神云集、群魔乱舞、以一抵百、砥砺前行//Problem L: Logic Puzzle

本文介绍了解决Mosaic拼图谜题的算法,这是一种类似于扫雷游戏的逻辑谜题。通过农村包围城市的策略,从边界开始逐步填充网格,确保每个数字周围黑色单元格的数量与数字相符。代码实现使用C++,展示了如何根据给定的线索数字来确定网格中哪些单元格应该被涂黑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

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:
在这里插入图片描述
Figure L.1: Illustration of the first sample
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 Sample Output 1
2 3
1 1 2 1 1
1 2 3 2 1
1 2 3 2 1
0 1 1 1 0
X.X
.X.
GCPC 2018 – Problem L: Logic Puzzle 23
Sample Input 2 Sample Output 2
1 2
0 0 1 1
0 1 1 1
0 1 1 1
impossible

题解

有点可惜,比赛后四分钟才A的,看少了一行
指导思想:农村包围城市。
a[i][j]的数字决定了an[i+1][j+1]是白格还是黑格。若a[i][j]>0的话,a[i+1][j+1]对应的九宫格内的数字全部减一;在一次内层(列)循环结束后,判断该行的数字是否==0,若不等于0则impossible。

代码如下:

#include<algorithm>
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<vector>
#include<queue>
#include<stack>
#include<cmath>
using namespace std;
#define ll long long
#define maxn 0x3f3f3f3f
int read()
{
    int sign=1,ans=0;
    char ch;
    ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
            sign=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        ans=(ans<<1)+(ans<<3)+(ch^48);
        ch=getchar();
    }
    return ans*sign;
}
int map1[105][105];
int ans[105][105];
int main()
{
    memset(ans,0,sizeof(ans));
    int n,m;
    cin>>n>>m;
    for(int i=1; i<=n+2; i++)
        for(int j=1; j<=m+2; j++)
            map1[i][j]=read();
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=m; j++)
        {
            if(map1[i][j]>0)
            {
                ans[i][j]=1;
                map1[i][j+1]--;
                map1[i][j]--;
                map1[i][j+2]--;
                map1[i+1][j+1]--;
                map1[i+1][j+2]--;
                map1[i+1][j]--;
                map1[i+2][j+1]--;
                map1[i+2][j+2]--;
                map1[i+2][j]--;
            }
            else if(map1[i][j]<0)
            {
                cout<<"impossible"<<'\n';
                return 0;
            }
        }
        for(int k=1; k<=m+2; k++)
        {
            if(map1[i][k]!=0)
            {
                cout<<"impossible"<<'\n';
                return 0;
            }
        }
    }
    for(int i=n; i<=n+2; i++)
    {
        for(int j=1; j<=m+2;j++)
        {
            if(map1[i][j]!=0)
            {
                cout<<"impossible"<<'\n';
                return 0;
            }
        }
    }
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=m; j++)
        {
            if(ans[i][j]==1)
                cout<<"X";
            else
                cout<<".";
        }
        cout<<'\n';
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_春与修罗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值