SSL2838 2017年11月6日提高组T1 矩阵(贪心)

来源:互联网 发布:程序员修改bug搞笑图 编辑:程序博客网 时间:2024/06/08 15:21

2017年11月6日提高组T1 矩阵

Description

给你一个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。

分析:对于每一行,统计负数的个数,若负数较多就把每个负数所在列取反,否则把这行取反,如果有一列取反了2次就是impossible,最后ans=min(ans,n+m-ans),最多操作n+m次。

代码

#include <cstdio>#define N 1005 using namespace std;long long a[N][N];int n,m,ans;bool v[N];int min(int x,int y){    return x<y?x:y;}int main(){//  freopen("b.in","r",stdin);//  freopen("b.out","w",stdout);    scanf("%d%d",&n,&m);    long long sum=0,now=0;    for (int i=1;i<=n;i++)        for (int j=1;j<=m;j++)        {            scanf("%lld",&a[i][j]);            now+=a[i][j];            if (a[i][j]<0) sum+=-a[i][j];                else sum+=a[i][j];        }    bool fl=false;    int i=1;    while (1)    {        if (i>n) i%=n;        if (fl) break;        int tot=0;        for (int j=1;j<=m;j++)            if (a[i][j]<0) tot++;        if (tot>=m/2)        {            for (int j=1;j<=m;j++)            {                now-=a[i][j]*2;                a[i][j]=-a[i][j];            }            ans++;        }        else             for (int j=1;j<=m;j++)                if (a[i][j]<0)                {                    if (v[j])                     {                        fl=true;                        break;                    }                    else                    {                        v[j]=true;                        for (int k=1;k<=n;k++)                        {                            now-=a[k][j]*2;                            a[k][j]=-a[k][j];                        }                        ans++;                    }                }        if (now==sum) break;        i++;    }    ans=min(ans,n+m-ans);    if (fl) printf("impossible");        else printf("%d",ans);    fclose(stdin);    fclose(stdout);} 
原创粉丝点击