题意:根据题目所提供的目标矩阵,你每次可以操作,每行或者每列全体加1(没有减1的操作),问是否能经过操作后达到目标矩阵;
思路:一道大模拟题,刚开始只考虑到添加列,其实应该行和列分别考虑,取最小值。无论是考虑行还是考虑列,一个道理,矩阵颠倒一下就行;
介绍从列添加的做法:
统计每行的最小值,超出最小值的部分,都应该通过添加列的方式弥补。
统计每列需要添加的最大值和该行的最小值相加,最后和目标矩阵对比;
//按照从列添加的方法 :mp1数组存储生成的矩阵,和mp初数组进行对比;
//a数组代表每行的最小值,b数组代表每列需要添加的最大值(而不是每列的最大值 )
//按照从列行加的方法 :mp2数组存储生成的矩阵,和mp初数组进行对比;
//c数组代表每列的最小值,d数组代表每行需要添加的最大值(而不是每行的最大值 )
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define max_n 510
typedef long long LL;
using namespace std;
int mp[max_n][max_n],mp1[max_n][max_n],mp2[max_n][max_n],a[max_n],b[max_n],c[max_n],d[max_n];
int main()
{
int n,m,t2=0,t1=0;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
{
a[i]=1010;
for(int j=1;j<=m;j++)
{
scanf("%d",&mp[i][j]);
a[i]=min(a[i],mp[i][j]);
}
t1+=a[i];
}
for(int j=1;j<=m;j++)
{
for(int i=1;i<=n;i++)
{
mp1[i][j]=a[i];
if(mp[i][j]>mp1[i][j])
{
b[j]=max(b[j],mp[i][j]-mp1[i][j]);
}
}
t1+=b[j];
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
mp1[i][j]+=b[j];
}
}
bool flag1=true,flag2=true;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(mp[i][j]!=mp1[i][j])
{
flag1=false;
break;
}
}
if(!flag1) break;
}
for(int j=1;j<=m;j++)
{
c[j]=1010;
for(int i=1;i<=n;i++)
{
c[j]=min(c[j],mp[i][j]);
}
t2+=c[j];
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
mp2[i][j]=c[j];
if(mp[i][j]>mp2[i][j])
{
d[i]=max(d[i],mp[i][j]-mp2[i][j]);
}
}
t2+=d[i];
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
mp2[i][j]+=d[i];
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(mp[i][j]!=mp2[i][j])
{
flag2=false;
break;
}
}
if(!flag2) break;
}
if(!flag1 && !flag2) printf("-1\n");
else
{
if(t1<=t2)
{
printf("%d\n",t1);
for(int i=1;i<=n;i++)
{
if(a[i])
{
for(int j=0;j<a[i];j++)
printf("row %d\n",i);
}
}
for(int i=1;i<=m;i++)
{
if(b[i])
{
for(int j=0;j<b[i];j++)
printf("col %d\n",i);
}
}
}
else
{
printf("%d\n",t2);
for(int i=1;i<=n;i++)
{
if(d[i])
{
for(int j=0;j<d[i];j++)
printf("row %d\n",i);
}
}
for(int i=1;i<=m;i++)
{
if(c[i])
{
for(int j=0;j<c[i];j++)
printf("col %d\n",i);
}
}
}
}
return 0;
}