题意
在给定 N×M 的全零矩阵中,每步操作可选择:
- 将一行中的所有元素
+1
- 将一列中的所有元素
+1
问对于给定的目标矩阵,如何操作能在最少步骤构造出目标矩阵,若不能,输出-1
。
解题思路
首先,找到目标矩阵 G 中的最小元素记为 x
,令
N×M
且所有元素均为 x 的矩阵为基准矩阵 B,则对于矩阵
G−B
,至少有一个元素为 0 ,故可以想象,当不考虑构造矩阵
G−B
的操作先后,其构造方法唯一。可暴力判断是否可行即可。
对于基准矩阵 B ,其最小构造步骤为 min(N, M) 。
代码
#include<bits/stdc++.h>
using namespace std;
int n, m, g[110][110], minR[110], c[110];
bool solve() {
for(int j=1, st;j<=m;j++) {
st = g[1][j] - minR[1];
for(int i=1;i<=n;i++) {
if(st != g[i][j] - minR[i])
return false;
}
c[j] = st;
}
return true;
}
int main()
{
memset(minR, 0x3f, sizeof(minR));
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
scanf("%d",&g[i][j]);
minR[i] = min(minR[i], g[i][j]);
}
if(solve() == false) printf("-1");
else {
if(n > m) {
int tmp = 0x3f3f3f3f;
for(int i=1;i<=n;i++)
tmp = min(tmp, minR[i]);
for(int i=1;i<=n;i++)
minR[i] -= tmp;
for(int j=1;j<=m;j++)
c[j] += tmp;
}
int cnt = 0;
for(int i=1;i<=n;i++)
cnt += minR[i];
for(int j=1;j<=m;j++)
cnt += c[j];
printf("%d\n", cnt);
for(int i=1;i<=n;i++)
for(int k=0;k<minR[i];k++)
printf("row %d\n", i);
for(int j=1;j<=m;j++)
for(int k=0;k<c[j];k++)
printf("col %d\n", j);
}
}