[构造] Codeforces 226D #140 (Div. 1) D. The table

有一个n*m的矩阵,每次可以将一列取负或者将一行取负,求一个方案使得每行每列的和都非负。
n,m<=100,元素绝对值<=100

如果有某一行或某一列为负 直接取反
这样整个矩阵的和肯定会变大 也就是说一定结束
每次操作至少使和增加 2 ,而和最大1003,最小 1003 ,所以总步数最多为 1003

#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;

const int N=105;

int n,m;
int a[N][N];
int sr[N],sc[N];
int r[N],c[N];
#define read(x) scanf("%d",&(x))

int main(){
  freopen("t.in","r",stdin);
  freopen("t.out","w",stdout);
  read(n); read(m);
  for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) read(a[i][j]),sr[i]+=a[i][j],sc[j]+=a[i][j];
  while (1){
    int k=0;
    for (int i=1;i<=n;i++) if (sr[i]<0) { k=i; break; }
    if (k){
      sr[k]=-sr[k]; r[k]^=1;
      for (int j=1;j<=m;j++)
    sc[j]-=a[k][j]<<1,a[k][j]=-a[k][j];
      continue;
    }
    k=0;
    for (int j=1;j<=m;j++) if (sc[j]<0) { k=j; break; }
    if (k){
      sc[k]=-sc[k]; c[k]^=1;
      for (int i=1;i<=n;i++)
    sr[i]-=a[i][k]<<1,a[i][k]=-a[i][k];
      continue;
    }
    break;
  }
  int tot=0;
  for (int i=1;i<=n;i++) tot+=r[i];
  printf("%d ",tot);
  for (int i=1;i<=n;i++) if (r[i]) printf("%d ",i); printf("\n");
  tot=0;
  for (int j=1;j<=m;j++) tot+=c[j];
  printf("%d ",tot);
  for (int j=1;j<=m;j++) if (c[j]) printf("%d ",j); printf("\n");
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值