正题
CF226D
题目大意
给一个n*m的矩阵,每次操作可以使一行或一列全部变号(+变-,-变+),问如何操作可以使所有行列之和都是正数
解题思路
考虑每次暴力找小于0的一行或一列,然后反转
因为每次反转肯定会使数字之和至少加2,且ai≤100a_i\leq 100ai≤100,数字之和最小为-1e6,最多反转到1e6,所以最多反转1e6次
时间复杂度 O(n4)O(n^4)O(n4)
code
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define N 110
using namespace std;
int n,m,pp,sum,a[N][N],s1[N],s2[N],q[N],qq[N];
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=n;++i)for(int j=1;j<=m;++j){scanf("%d",&a[i][j]);s1[i]+=a[i][j];s2[j]+=a[i][j];}while(1){pp=0;for(int i=1;i<=n&&!pp;++i)if(s1[i]<0)pp=i;if(pp){q[pp]^=1;for(int i=1;i<=m;++i){s1[pp]-=a[pp][i]*2;s2[i]-=a[pp][i]*2;a[pp][i]*=-1;}}else{for(int i=1;i<=m&&!pp;++i)if(s2[i]<0)pp=i;if(pp){qq[pp]^=1;for(int i=1;i<=n;++i){s1[i]-=a[i][pp]*2;s2[pp]-=a[i][pp]*2;a[i][pp]*=-1;}}else break;}}sum=0;for(int i=1;i<=n;++i)if(q[i])sum++;printf("%d",sum);for(int i=1;i<=n;++i)if(q[i])printf(" %d",i);putchar(10);sum=0;for(int i=1;i<=m;++i)if(qq[i])sum++;printf("%d",sum);for(int i=1;i<=m;++i)if(qq[i])printf(" %d",i);return 0;
}