2020 ICPC Shanghai Site B. Mine Sweeper II 题解 构造 鸽巢原理

Mine Sweeper II

题目描述

A mine-sweeper map X X X can be expressed as an n × m n\times m n×m grid. Each cell of the grid is either a mine cell or a non-mine cell. A mine cell has no number on it. Each non-mine cell has a number representing the number of mine cells around it. (A cell is around another cell if they share at least one common point. Thus, every cell that is not on the boundary has 8 8 8 cells around it.) The following is a 16 × 30 16\times 30 16×30 mine-sweeper map where a flagged cell denotes a mine cell and a blank cell denotes a non-mine cell with number 0.

Given two mine-sweeper maps A , B A, B A,B of size n × m n\times m n×m, you should modify at most ⌊ n m 2 ⌋ \left\lfloor\frac{nm}{2}\right\rfloor ⌊2nm⌋ (i.e. the largest nonnegative integer that is less than or equal to n m 2 \frac{nm}{2} 2nm) cells in B B B (from a non-mine cell to a mine cell or vice versa) such that the sum of numbers in the non-mine cells in A A A and the sum of numbers in the non-mine cells in B B B are the same. (If a map has no non-mine cell, the sum is considered as 0 0 0.)

If multiple solutions exist, print any of them. If no solution exists, print "-1" in one line.

输入描述

The first line contains two integers n , m   ( 1 ≤ n , m ≤ 1000 ) n, m\,(1\le n,m \le 1000) n,m(1≤n,m≤1000), denoting the size of given mine-sweeper maps.

The i i i-th line of the following n n n lines contains a length- m m m string consisting of "." and "X" denoting the i i i-th row of the mine-sweeper map A A A. A "." denotes for a non-mine cell and an "X" denotes for a mine cell.

The i i i-th line of the following n n n lines contains a length- m m m string consisting of "." and "X" denoting the i i i-th row of the mine-sweeper map B B B. A "." denotes for a non-mine cell and an "X" denotes for a mine cell.

输出描述

If no solution exists, print "-1" in one line.

Otherwise, print n n n lines denoting the modified mine-sweeper map B B B. The i i i-th line should contain a length- m m m string consisting of "." and "X" denoting the i i i-th row of the modified map B B B. A "." denotes for a non-mine cell and an "X" denotes for a mine cell.

Please notice that you need not print the numbers on non-mine cells since these numbers can be determined by the output mine-sweeper map.

题面翻译

扫雷地图有 n 行 m 列。每个格子是地雷或者空地。每个空地显示一个数字,数字代表周围 8 个格子中是地雷的格子的数量。你可以在一次操作中,将一个地雷修改为空地,或者将一个空地修改为地雷。给定两张扫雷地图 A 和 B,请对 B 进行不超过 ⌊ n m 2 ⌋ \lfloor\frac{nm}{2}\rfloor ⌊2nm⌋ 次操作,使得 B 地图所有空地上的数字之和等于 A 地图所有空地上的数字之和。

样例 #1

样例输入 #1

复制代码
2 4
X..X
X.X.
X.X.
.X..

样例输出 #1

复制代码
X.XX
.X..

思路

考虑两种方案。方案一:将 B 改为 A。方案二:将 B 改成 A 的相反,即对应位置若 A 为地雷则改后的 B 为空地,反之改后的B为地雷。对于每个格子的修改,都恰好存在于两种方案之一。所以两种方案的操作次数之和为 n m nm nm。根据鸽巢原理,在两种方案中,一定存在一种方案的操作次数不超过 ⌊ n m 2 ⌋ \lfloor\frac{nm}{2}\rfloor ⌊2nm⌋。

代码

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);

    int n, m;
    cin >> n >> m;
    vector<vector<char>> a(n, vector<char>(m));
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            cin >> a[i][j];
    vector<vector<char>> b(n, vector<char>(m));
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            cin >> b[i][j];
    // 方案一:将B改成A
    // 方案二:将B改成A的相反,即若A为地雷则改后的B为空地,反之改后的B为地雷
    int cnt = 0; // 统计方案一需要的步数
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            if (a[i][j] != b[i][j])
                cnt++;
    if (cnt <= n * m / 2) // 如果方案一满足条件
    {
        // 输出方案一的结果
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m; j++)
                cout << a[i][j];
            cout << '\n';
        }
    }
    else // 如果方案一步数不满足条件,则根据鸽巢原理,方案二一定满足条件
    {
        // 输出方案二的结果
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m; j++)
                cout << ((a[i][j] == '.') ? 'X' : '.');
            cout << '\n';
        }
    }

    return 0;
}
相关推荐
你撅嘴真丑13 小时前
第九章-数字三角形
算法
在路上看风景13 小时前
19. 成员初始化列表和初始化对象
c++
uesowys13 小时前
Apache Spark算法开发指导-One-vs-Rest classifier
人工智能·算法·spark
zmzb010313 小时前
C++课后习题训练记录Day98
开发语言·c++
ValhallaCoder13 小时前
hot100-二叉树I
数据结构·python·算法·二叉树
董董灿是个攻城狮13 小时前
AI 视觉连载1:像素
算法
念风零壹14 小时前
C++ 内存避坑指南:如何用移动语义和智能指针解决“深拷贝”与“内存泄漏”
c++
智驱力人工智能14 小时前
小区高空抛物AI实时预警方案 筑牢社区头顶安全的实践 高空抛物检测 高空抛物监控安装教程 高空抛物误报率优化方案 高空抛物监控案例分享
人工智能·深度学习·opencv·算法·安全·yolo·边缘计算
孞㐑¥14 小时前
算法——BFS
开发语言·c++·经验分享·笔记·算法
月挽清风14 小时前
代码随想录第十五天
数据结构·算法·leetcode