【蓝桥·算法双周赛 第 9 场 小白入门赛】盖印章【算法赛】题解(数学+解方程)

思路

考虑到题目中的规则,每个印章图案的边必须和网格图边重合,网格图上的每一个格子最多只能被一个印章图案覆盖,印章的图案在网格图上必须是完整的。这意味着每个印章图案都会覆盖一个独立的、完整的区域,且这些区域不会相互重叠。

设第一种印章覆盖的格子数为 x x x,第二种印章覆盖的格子数为 y y y,那么它们的总覆盖格子数为 c n t = x + y cnt = x + y cnt=x+y。同时,题目给出两种印章的使用次数之和为 k k k。由于每种印章的使用次数必须是整数,我们可以设第一种印章的使用次数为 a a a,第二种印章的使用次数为 b b b,那么 a + b = k a + b = k a+b=k。又有 3 a + 2 b = c n t 3a + 2b = cnt 3a+2b=cnt。

这两个方程构成一个线性方程组,可以使用消元法求解。先将第二个方程乘以2得到 2 a + 2 b = 2 k 2a + 2b = 2k 2a+2b=2k,然后将第一个方程减去这个得到 a = c n t − 2 k a = cnt - 2k a=cnt−2k。这就是印章A的使用次数。

接着,将求得的印章A的使用次数 a a a 代入第二个方程 a + b = k a + b = k a+b=k,可以解得 b = k − a = 3 k − c n t b = k - a = 3k - cnt b=k−a=3k−cnt。这就是印章B的使用次数。

首先从输入中读取三个整数 nmk,这三个整数分别表示网格图的行数、列数和两种印章的使用次数之和。然后,通过一个循环,读取 n × m n \times m n×m 个字符,每个字符表示一个网格图上的格子,字符 '1' 表示这个位置被印章图案覆盖,字符 '0' 表示这个位置没有被覆盖。在读取每个字符的同时,如果字符为 '1',则将计数器 cnt 加一,这样 cnt 就表示了印章覆盖的格子总数。

在读取完所有字符之后,输出两种印章的使用次数。第一种印章的使用次数为 (cnt - 2 * k),第二种印章的使用次数为 (3 * k - cnt)。这样就得到了每种印章的使用次数。


AC代码

cpp 复制代码
#include <algorithm>
#include <cmath>
#include <cstring>
#include <iostream>
#define AUTHOR "HEX9CF"
using namespace std;
using ll = long long;

const int N = 1e6 + 7;
const int INF = 0x3f3f3f3f;

ll n, m, k;
ll cnt = 0;

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

	cin >> n >> m >> k;
	for (int i = 1; i <= n * m; i++) {
		char t;
		cin >> t;
		cnt += (t == '1');
	}
	cout << (cnt - 2 * k) << " " << (3 * k - cnt) << "\n";
	return 0;
}

相关推荐
灵感__idea3 小时前
Hello 算法:贪心的世界
前端·javascript·算法
钢琴上的汽车软件4 小时前
C 语言中const与指针:三种常见写法辨析
c语言·指针和const
ZK_H4 小时前
嵌入式c语言——关键字其6
c语言·开发语言·计算机网络·面试·职场和发展
澈2074 小时前
深入浅出C++滑动窗口算法:原理、实现与实战应用详解
数据结构·c++·算法
ambition202424 小时前
从暴力搜索到理论最优:一道任务调度问题的完整算法演进历程
c语言·数据结构·c++·算法·贪心算法·深度优先
cmpxr_4 小时前
【C】原码和补码以及环形坐标取模算法
c语言·开发语言·算法
qiqsevenqiqiqiqi5 小时前
前缀和差分
算法·图论
代码旅人ing5 小时前
链表算法刷题指南
数据结构·算法·链表
Yungoal5 小时前
常见 时间复杂度计算
c++·算法
yashuk5 小时前
C语言实现PAT练习及算法学习笔记,还有SQLite介绍
c语言·sqlite·开源项目·算法学习·pat练习