ARC176A 01 Matrix Again 题解
题意:给定 \(n\),以及 \(m\) 对 \((a_i,b_i)\),你需要构造一个 \(n \times n\) 的 \(01\) 矩阵使得每行每列都恰好有 \(m\) 个数为 \(1\),且 \((a_i,b_i)\) 的位置上的数必须为 \(1\)。
首先我们考虑 \(m=1\) 的情况,会发现最终的 \(1\) 的分布一定是形如一条斜线。
进而我们会发现如果选满足 \(i+j \equiv k \pmod{n}\) 的所有 \((i,j)\)(\(k\) 为一个定值,即形如一条斜线的点)填上 \(1\),那么恰好满足每行每列都有一个数为 \(1\)。因为题目要求每行每列都恰好有 \(m\) 个数为 \(1\),于是我们选 \(m\) 个不同的 \(k\) 即可。但是题目还要求了 \((a_i,b_i)\) 必须为 \(1\),所以对于每一个 \(k=(a_i+b_i) \bmod n\) 都必须选。因为输入的 \((a_i,b_i)\) 为 \(m\) 个,所以必须选的 \(k\) 不超过 \(m\) 个,一定有解。其余的 \(k\) 随便选即可。时间复杂度 \(O(nm)\)。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int MAXN = 2e5 + 10;
int n,m,sum;
bool vis[MAXN];
signed main() {
cin >> n >> m;
for(int i = 1,a,b;i <= m;i++) {
cin >> a >> b;
if(!vis[(a + b) % n])
vis[(a + b) % n] = 1,sum++;
} printf("%lld\n",n * m);
for(int i = 0;i < n;i++) {
if(vis[i] || sum < m) {
if(vis[i] == false) sum++;
for(int j = 1;j <= n;j++)
printf("%lld %lld\n",j,(i - j + 2 * n - 1) % n + 1);
}
} return 0;
}
本文作者:Creeper_l
本文链接:https://www.cnblogs.com/Creeperl/p/18165669
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步