挑战程序设计竞赛 2章习题 Aizu - 0525 Osenbei BFS
地址 https://vjudge.net/problem/Aizu-0525
IOI 糖果公司使用自公司成立以来一直沿用的传统方法烘烤米果。 这种传统方法是将米果的正面用炭火烘烤一段时间,正面烤好后将其翻面,再将背面用炭火烘烤一段时间。 在保持这一传统的同时,米果是用机器烘烤的。 机器烘烤的米果呈长方形,纵行为 R(1≤R≤10),横列为 C(1≤C≤10000)。
正常情况下,机器自动运行,当正面烘烤完成后,机器同时将米果翻转过来,烘烤背面。
有一天,在烘烤米饼时,就在米饼翻面之前发生了地震,导致部分米饼被翻面。
幸运的是,炭火依然完好,但如果再烘烤正面,烘烤时间就会超过公司成立以来的传统规定,米果的正面就会烧焦,无法作为产品出厂。
因此,匆忙将机器改为手动操作,只翻转尚未翻转的米果。 该机器可以同时翻转横排和竖列,但遗憾的是,它不能逐个翻转米果。
如果翻转米果的时间过长,地震时未翻转的米果正面就会过熟,无法作为产品出厂。
横排也要翻面一次。 还要考虑没有横行被翻转或没有竖列被翻转的情况。 请编写一个程序,输出可装运的米果的最大数量。
假设地震发生后,米果立即处于下图所示的状态。 黑圈表示正面烧焦,白圈表示背面烧焦。
多组数据 以输入 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; }
#include <iostream>
using namespace std;
int r, c; int gra[15][10010]; int ans = -1; void flip(int row) { for (int j = 0; j < c; j++) { gra[row][j] ^= 1;} } void reflip(int row) { flip(row); } void Check() { int sum = 0; for (int i = 0; i < c; i++) { int a = 0; int b = 0; for (int j = 0; j < r; j++) { if (gra[j][i] == 1) {a++;} else {b++;} } sum += max(a, b); } ans = max(sum, ans); } void dfs(int curr) { if (curr >= r) { //检验当前的 Check(); return; } //当前 选择或者不选择 flip(curr); dfs(curr + 1); reflip(curr); dfs(curr+1); return; } void solve() { ans = -1; dfs(0); cout << ans << endl; return ; } int main() { while (cin >> r >> c) { if (r == 0 && c == 0) break; for (int i = 0; i < r; i++) { for (int j = 0; j < c; j++) { cin >> gra[i][j]; } } solve(); } return 0; }
作 者: itdef
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
![阿里打赏](https://files.cnblogs.com/files/itdef/ali2.bmp)
![微信打赏](https://files.cnblogs.com/files/itdef/weixin2.bmp)