Problem Description
Harry Potter has a difficult homework. Given a rectangular table, consisting of n × m cells. Each cell of the table contains the integer. Harry knows how to use two spells: the first spell change the sign of the integers in the selected row, the second — in the selected column. Harry's task is to make non-negative the sum of the numbers in each row and each column using these spells.
Alone, the boy can not cope. Help the young magician!
Input
The first line contains two integers n and m (1 ≤ n, m ≤ 100) — the number of rows and the number of columns.
Next n lines follow, each contains m integers: j-th integer in the i-th line is ai, j (|ai, j| ≤ 100), the number in the i-th row and j-th column of the table.
The rows of the table numbered from 1 to n. The columns of the table numbered from 1 to m.
Output
In the first line print the number a — the number of required applications of the first spell. Next print a space-separated integers — the row numbers, you want to apply a spell. These row numbers must be distinct!
In the second line print the number b — the number of required applications of the second spell. Next print b space-separated integers — the column numbers, you want to apply a spell. These column numbers must be distinct!
If there are several solutions are allowed to print any of them.
Examples
Input |
4 1 -1 -1 -1 -1 |
Output |
4 1 2 3 4 0 |
Input |
2 4 -1 -1 -1 2 1 1 1 1 |
Output |
1 1 1 4 |
题意:
给出一个 n*m 的矩阵,其元素绝对值均小于 100,现在可以让某一行或一列的所有数取反,要求构造一个解,使得每一行每一列的和都是非负数
思路:
首先统计矩阵每一行每一列的和,然后去枚举行列的和,当某一行的值小于 0,那么将这一行直接翻转,再对行列和进行相应处理,直到没有负值
由于矩阵元素最多为 100 个,元素值范围为 -100~100,因此,整个矩阵和的范围为 [-10000,10000],故而当某一行列的和为负时,将其进行翻转后,和至少 +2,因此最多枚举 100^4 即可令整个矩阵的行列和为正
代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<bitset>
#define EPS 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LL long long
const int MOD = 1E9+7;
const int N = 5000+5;
const int dx[] = {-1,1,0,0,-1,-1,1,1};
const int dy[] = {0,0,-1,1,-1,1,-1,1};
using namespace std;
LL a[N][N];
LL sumRow[N],sumCol[N];
int row[N],col[N];
vector<int>resRow,resCol;
int main() {
int n,m;
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++) {
scanf("%lld",&a[i][j]);
sumRow[i]+=a[i][j];
sumCol[j]+=a[i][j];
}
}
while(true) {
for(int i=1; i<=n; i++) {
if(sumRow[i]<0) {
sumRow[i]=0;
for(int j=1; j<=m; j++) {
a[i][j]=-a[i][j];
sumRow[i]+=a[i][j];
sumCol[j]=sumCol[j]-(-a[i][j])+a[i][j];
}
row[i]+=1;
}
}
for(int j=1; j<=m; j++) {
if(sumCol[j]<0) {
sumCol[j]=0;
for(int i=1; i<=n; i++) {
a[i][j]=-a[i][j];
sumCol[j]+=a[i][j];
sumRow[i]=sumRow[i]-(-a[i][j])+a[i][j];
}
col[j]+=1;
}
}
bool flag=false;
for(int i=1; i<=n; i++) {
if(sumRow[i]<0) {
flag=true;
}
}
for(int i=1; i<=m; i++) {
if(sumCol[i]<0) {
flag=true;
}
}
if(!flag)
break;
}
int num1=0,num2=0;
for(int i=1; i<=n; i++) {
if(row[i]%2==1) {
resRow.push_back(i);
num1++;
}
}
for(int i=1; i<=m; i++) {
if(col[i]%2==1) {
resCol.push_back(i);
num2++;
}
}
printf("%d ",num1);
for(int i=0; i<num1; i++)
printf("%d ",resRow[i]);
printf("\n");
printf("%d ",num2);
for(int i=0; i<num2; i++)
printf("%d ",resCol[i]);
printf("\n");
return 0;
}