#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=100;
struct node{
int t;
int time=0,r;
};
int l[maxn][maxn],r[maxn][maxn],l1[maxn][maxn],r1[maxn][maxn],n,m,cnt;
void init(int (*a)[maxn],int (*b)[maxn],node *record,int n,int m,int type){
for(int i=0;i<n;i++)
for(int j=0;j<m;j++){
if(a[i][j]==0)
break;
if(j==m-1){
for(int k=0;k<m;k++)
b[i][k]=*min_element(a[i],a[i]+maxn);
record[cnt].t=type;
record[cnt].r=i+1;
record[cnt++].time=b[i][0];
}
}
}
bool judge(int (*a)[maxn],int (*b)[maxn],int n,int m){
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(a[i][j]!=b[i][j])
return false;
return true;
}
void printf(node *record){
int cnt2=0;
for(int i=0;i<cnt&&record[i].time!=0;i++)
{cnt2=cnt2+record[i].time-1;}
printf("%d\n",cnt+cnt2);
for(int i=0;i<cnt;i++)
for(int j=0;j<record[i].time;j++){
if(record[i].t==1)
printf("row %d\n",record[i].r);
if(record[i].t==-1)
printf("col %d\n",record[i].r);
}
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
cnt=0;
node rec[maxn];
memset(l,inf,sizeof(l));
memset(r,inf,sizeof(r));
memset(l1,0,sizeof(l1));
memset(r1,0,sizeof(r1));
for(int i=0;i<n;i++)
for(int j=0;j<m;j++){
scanf("%d",&l[i][j]);
r[j][i]=l[i][j];
}
init(l,l1,rec,n,m,1);
if(judge(l,l1,n,m)){
printf(rec);
continue;
}
/*for(int i=0;i<n;i++){
for(int j=0;j<m;j++)
printf("%d ",l1[i][j]);
printf("\n");}///debug*/
init(r,r1,rec,m,n,-1);
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
/*if(l1[i][j]==inf) l1[i][j]=0;
if(r1[j][i]==inf) r1[j][i]=0;*/
l1[i][j]=l1[i][j]+r1[j][i];
}
/*for(int i=0;i<n;i++){
for(int j=0;j<m;j++)
printf("%d ",l1[i][j]);
printf("\n");
}///db*/
if(judge(l,l1,n,m))
printf(rec);
else printf("-1\n");
}
return 0;
}
思路是对的,就是遍历矩阵的每一行,如果全部为零则把一个空矩阵对应的行的每一个元素加上那个数,然后同样的方法对列进行变换,如果最终结果和目标矩阵一致就是可以的。然而,在进行列变化这里我又用了个矩阵(主要是计组的老师说用列遍历行效率会很低,其实我多开一个循环效率更低。。。然后就TLE 了)以上是TLE代码。。。。
AC代码:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 100
#define MAX_VAL 1000
int n, m, cnt = 0;
int g[SIZE][SIZE];
int row[SIZE], col[SIZE];
void row_operate(void)
{
for (int i = 0; i < n; i++) {
row[i] = MAX_VAL;
for (int j = 0; j < m; j++)
if (g[i][j] < row[i]) row[i] = g[i][j];
for (int j = 0; j < m; j++)
g[i][j] -= row[i];
cnt += row[i];
}
}
void col_operate(void)
{
for (int j = 0; j < m; j++) {
col[j] = MAX_VAL;
for (int i = 0; i < n; i++)
if (g[i][j] < col[j]) col[j] = g[i][j];
for (int i = 0; i < n; i++)
g[i][j] -= col[j];
cnt += col[j];
}
}
int main(void)
{
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
scanf("%d", &g[i][j]);
if (n <= m) {
row_operate();
col_operate();
}
else {
col_operate();
row_operate();
}
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
if (g[i][j]) {
printf("-1\n");
exit(0);
}
printf("%d\n", cnt);
for (int i = 0; i < n; i++)
for (int k = 0; k < row[i]; k++)
printf("row %d\n", i + 1);
for (int j = 0; j < m; j++)
for (int k = 0; k < col[j]; k++)
printf("col %d\n", j + 1);
return 0;
}
这个思路上做了个优化,就是直接在原矩阵进行减法,即扫过一行(或一列)找出最小的数,原矩阵的那一行(或那一列)直接减去对应行(列)的最小的数,最后判断时就不用比较两个矩阵是否相等,直接判断是不是“0”矩阵就可以了。