• 挑战程序设计竞赛 2章习题 Aizu


    地址 https://vjudge.net/problem/Aizu-0525

    题目大意是给一个 R行C列的二维数组(只有01)
    可以进行某一行和某一列的翻转,输出能得到的最大的0的个数
    多组数据 以输入 0 0 结束
    1 ≤ R ≤ 10, 1 ≤ C ≤ 10 000
    入力例
    2 5
    0 1 0 1 0
    1 0 0 0 1
    3 6
    1 0 0 0 1 0
    1 1 1 0 1 0
    1 0 1 1 0 1  
    0 0
    出力例
    9
    15

    解答

    查看数据范围

    以每行是否翻转作为状态,那么一共有210状态就是1024个

    每列是否翻转取决于每列上0多还是1多

    所以我们遍历每行是否翻转的状态, 然后按照每列最多的0或者1的数目累加 就是能够得到的最多0的数目

    使用位运算记录每行是否已经翻转  

    // 112355555.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
    //
    
    #include <iostream>
    #include <unordered_set>
    #include <algorithm>
    
    using namespace std;
    
    
    /*
    入力例
    2 5
    0 1 0 1 0
    1 0 0 0 1
    3 6
    1 0 0 0 1 0
    1 1 1 0 1 0
    1 0 1 1 0 1
    0 0
    出力例
    9
    15
    
    //==============
    3 22
    1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
    1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
    1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
    3 22
    1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
    1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
    1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
    3 22
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
    1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
    3 22
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    1 1 1 1 1 0 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1
    1 1 1 1 1 0 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1
    3 22
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    1 1 1 1 1 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1
    1 1 1 1 1 0 1 1 1 1 1 0 1 0 1 0 1 1 1 1 1 1
    9 22
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    1 1 1 1 1 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1
    1 1 1 1 1 0 1 1 1 1 1 0 1 0 1 0 1 1 1 1 1 1
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    1 1 1 1 1 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1
    1 1 1 1 1 0 1 1 1 1 1 0 1 0 1 0 1 1 1 1 1 1
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    1 1 1 1 1 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1
    1 1 1 1 1 0 1 1 1 1 1 0 1 0 1 0 1 1 1 1 1 1
    0 0
    */
    
    const int N = 100010;
    int arr[20][N];
    
    int c, r;
    int ans = 0;
    
    unordered_set<int> ss;
    
    //第i行翻转1次
    void Reverse(int idx) {
        for (int i = 0; i < r; i++) {
            arr[idx][i] ^= 1;
        }
    }
    
    int calc()
    {
        int sum = 0;
        //逐列计算0 1的个数 取个数多的加上
        for (int i = 0; i < r; i++) {
            int One_Count = 0; int Zero_Count = 0;
            for (int j = 0; j < c; j++) {
                if (arr[j][i] == 1) One_Count++;
                else Zero_Count++;
            }
            sum += max(One_Count, Zero_Count);
        }
    
        return sum;
    }
    
    
    void dfs(int reverIdx)
    {
        ans = max(ans, calc());
    
        for (int i = 0; i < c; i++) {
            int tmp = reverIdx ^ (1 << i);
            if (ss.count(tmp) == 0) {
                ss.insert(tmp);
                //没尝试过的都 进行计算
                Reverse(i);
                //计算得到最多的0
                ans = max(ans, calc());
                dfs(tmp);
                Reverse(i);
            }
        }
    }
    
    
    int main()
    {
        while (1) {
            cin >> c >> r;
            ans = 0; ss.clear();
            if (c == 0 && r == 0) break;
    
            for (int i = 0; i < c; i++) {
                for (int j = 0; j < r; j++) {
                    cin >> arr[i][j];
                }
            }
    
            dfs(0);
            cout << ans << endl;
        }
    
        return 0;
    }
    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    Spring 事务管理
    016 sleep,wait,yield,join区别
    013 GC机制
    011 CountDownLatch,CyclicBarrier和Semaphore
    012 public等关键字可见性
    010 JVM类加载
    009 JVM内存结构以及GC机制
    008 BlockingQueue理解
    python3 正则表达式
    python django
  • 原文地址:https://www.cnblogs.com/itdef/p/14561323.html
Copyright © 2020-2023  润新知