挑戰程序設計競賽 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.rzrgm.cn/itdef/
B站算法視頻題解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
歡迎c c++ 算法愛好者 windows驅動愛好者 服務器程序員溝通交流
如果覺得不錯,歡迎點贊,你的鼓勵就是我的動力
歡迎轉帖 請保持文本完整并注明出處
技術博客 http://www.rzrgm.cn/itdef/
B站算法視頻題解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
歡迎c c++ 算法愛好者 windows驅動愛好者 服務器程序員溝通交流
如果覺得不錯,歡迎點贊,你的鼓勵就是我的動力
浙公網安備 33010602011771號