现在的位置: 首页 > 综合 > 正文

Codeforces 226D The table 贪心

2018年04月25日 ⁄ 综合 ⁄ 共 1355字 ⁄ 字号 评论关闭

题意:给定n * m(n m <= 100)的矩阵,没分数字的绝对值<=100,现在想通过翻转一行或者一列的重复操作(不能出现相同的操作),使得所有行和列的

         和都>=0,问任意一组能满足条件的行列翻转方法。

题解:cf 上好像每次比赛都有贪心的样子。因为n m <= 100,所以一共最多有200次翻转操作,每次更新矩阵。但是这样可能会有一种操作重复,但是最多

         两次因为贪心能保证这样的性质,随后再搞一下就好了。


Sure原创,转载请注明出处。

#include <iostream>
#include <cstdio>
#include <memory.h>
#include <algorithm>
using namespace std;
const int maxn = 102;
int map[maxn][maxn],rr[maxn << 1],rc[maxn << 1];
int m,n,tr,tc;

void read()
{
    tr = tc = 0;
    for(int i=1;i<=m;i++)
    {
        for(int j=1;j<=n;j++)
        {
            scanf("%d",&map[i][j]);
        }
    }
    return;
}

int check()
{
    int bjr = -1,bjc = -1;
    int sr = 0,sc = 0;
    for(int i=1;i<=m;i++)
    {
        int sum = 0;
        for(int j=1;j<=n;j++)
        {
            sum += map[i][j];
        }
        if(sum < sr)
        {
            sr = sum;
            bjr = i;
        }
    }
    for(int j=1;j<=n;j++)
    {
        int sum = 0;
        for(int i=1;i<=m;i++)
        {
            sum += map[i][j];
        }
        if(sum < sc)
        {
            sc = sum;
            bjc = j;
        }
    }
    if(sr == 0 && sc == 0) return 0;
    return sr < sc ? bjr : (-bjc);
}

int gao(int *s,int num)
{
    int l = 0,top = 0;
    while(l < num)
    {
        int r = l+1;
        int cnt = 1;
        while(r < num && s[l] == s[r])
        {
            r++;
            cnt++;
        }
        if(cnt & 1)
        {
            s[top++] = s[l];
        }
        l = r;
    }
    return top;
}

void solve()
{
    while(true)
    {
        int val = check();
        if(val == 0) break;
        if(val > 0)
        {
            rr[tr++] = val;
            for(int i=1;i<=n;i++)
            {
                map[val][i] = -map[val][i];
            }
        }
        else
        {
            val = -val;
            rc[tc++] = val;
            for(int i=1;i<=m;i++)
            {
                map[i][val] = -map[i][val];
            }
        }
    }
    sort(rr , rr + tr);
    sort(rc , rc + tc);
    tr = gao(rr , tr);
    tc = gao(rc , tc);
    printf("%d",tr);
    for(int i=0;i<tr;i++)
    {
        printf(" %d",rr[i]);
    }
    puts("");
    printf("%d",tc);
    for(int i=0;i<tc;i++)
    {
        printf(" %d",rc[i]);
    }
    puts("");
    return;
}

int main()
{
    while(~scanf("%d %d",&m,&n))
    {
        read();
        solve();
    }
    return 0;
}

抱歉!评论已关闭.