[暴力]Matrix

题目描述

给你一个N*M 的矩阵,矩阵里面的元素要么是正数,要么是负数,它们的绝对值不大
于10000。现在你可以对矩阵进行两种操作:
1、将某一列的元素全部取反。
2、将某一行的元素全部取反。
你可以执行任意次操作。
Task:通过以上两种操作如果可以将整个矩阵的元素全变为正数的话,则输出最少的操
作次数,否则输出“impossible”(不包括双引号)。

Input

输入文件的第一行有两个整数n 和m(1≤n,m≤1000),表示矩阵的大小。
接下来有N 行,每行M 个数,每个数之间有一个空格。

Output

通过以上两种操作如果可以将整个矩阵的元素全变为正数的话,则输出最少的操作次
数,否则输出“impossible”(不包括双引号)。

Sample Input

2 4
3 7 -6 1
-2 -6 8 -4
Sample Output

2
Hint

对于100%的数据,2≤N,M≤1000

分析

矩阵题真神奇系列
枚举行,判断该行负数多还是少
多的直接反了这一行
少的逐列取反
同时做优化:如果某行或某列反了两次或以上,必定impossible
(这程序好像不是AC标程呢)

#include <iostream>
#include <cstdio>
#define rep(i,a,b) for (i=a;i<=b;i++)
using namespace std;
int n,m;
int a[1001][1001];
int rc[1001],cc[1001];
int zfr[1001],zfc[1001];
int i,j;
int f,z;
int ans;
int main()
{
//  freopen("matrix.in","r",stdin);
//  freopen("matrix.out","w",stdout);
    scanf("%d%d",&n,&m);
    rep(i,1,n)
    {
        rep(j,1,m)
        {
            scanf("%d",&a[i][j]);
            zfc[j]=1;
        }
        zfr[i]=1;
    }
    rep(i,1,n)
    {
        f=z=0;
        rep(j,1,m)
        if (a[i][j]*zfr[i]*zfc[j]<0) f++; else z++;
        if (f<z)
        rep(j,1,m)
        if (a[i][j]*zfr[i]*zfc[j]<0)
        {
            zfc[j]=-zfc[j];
            cc[j]++;
            if (cc[j]==2)
            {
                printf("impossible");
                return 0;
            }
            ans++;
        }
        if (f>=z)
        {
            zfr[i]=-zfr[i];
            rc[i]++;
            if (rc[i]==2)
            {
                printf("impossible");
                return 0;
            }
            ans++;
        }
    }
    printf("%d",ans);
}

猜你喜欢

转载自blog.csdn.net/ssl_qyh0ice/article/details/80029992