[CodeForces] CF226D The table

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
Copy
4 1
-1
-1
-1
-1
Output
Copy
4 1 2 3 4 
0
Input
Copy
2 4
-1 -1 -1 2
1 1 1 1
Output
Copy
1 1 
1 4

题目解析

输出有点玄学。

大概意思就是先输出行、列最小交换几次,然后输出交换了哪一行

我的做法是贪心,反复judge每一行、列的和,发现负的就翻转次数++,不停地翻转小于0的行列,总会让每行每列都变得大于0的。

最后,因为翻转两次=不翻转,所以最后要输出次数&1。挺好玩的,神题。

Code

#include<iostream>
#include<cstdio>
using namespace std;

int n,m;
int a[105][105];
int sumx[105],sumy[105];
int flagx[105],flagy[105];
int ans1,ans2;

inline int judge_x() {
    for(int i = 1;i <= n;i++) {
        if(sumx[i] < 0) return i;
    }
    return 0;
}

inline int judge_y() {
    for(int i = 1;i <= m;i++) {
        if(sumy[i] < 0) return i;
    }
    return 0;
}

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]);
            sumx[i] += a[i][j];
            sumy[j] += a[i][j];
        }
    }
    while(1) {
        int tmpx = judge_x();
        int tmpy = judge_y();
        if(!tmpx && !tmpy) break;
        if(tmpx) {
            flagx[tmpx]++;
            sumx[tmpx] = 0;
            for(int i = 1;i <= m;i++) {
                int k = -a[tmpx][i];
                sumy[i] = sumy[i] - a[tmpx][i] + k;
                a[tmpx][i] = k;
                sumx[tmpx] += k;
            }
        } else {
            flagy[tmpy]++;
            sumy[tmpy] = 0;
            for(int i = 1;i <= n;i++) {
                int k = -a[i][tmpy];
                sumx[i] = sumx[i] - a[i][tmpy] + k;
                a[i][tmpy] = k;
                sumy[tmpy] += k;
            }
        }
    }
    for(int i = 1;i <= n;i++) if(flagx[i] & 1) ans1++;
    for(int i = 1;i <= m;i++) if(flagy[i] & 1) ans2++;
    printf("%d ",ans1);
    for(int i = 1;i <= n;i++) {
        if(flagx[i] & 1) printf("%d ",i);
    }
    printf("\n%d ",ans2);
    for(int i = 1;i <= m;i++) {
        if(flagy[i] & 1) printf("%d ",i);
    }
    printf("\n");
    return 0;
}

 

转载于:https://www.cnblogs.com/floatiy/p/9483050.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值