• [转] AOJ 0525 Osenbei《挑战程序设计竞赛(第2版)》练习题答案


    来自 码农场 » AOJ 0525 Osenbei《挑战程序设计竞赛(第2版)》练习题答案

    只把代码复制过来,原博的其他分析请看链接。

     1 #include <iostream>
     2 #include <bitset>
     3 #include <algorithm>
     4  
     5 using namespace std;
     6  
     7 bitset<10000> cookie[10];
     8  
     9 ///////////////////////////SubMain//////////////////////////////////
    10 int main(int argc, char *argv[])
    11 {
    12  
    13     int R, C;
    14     while(cin >> R >> C && R > 0)
    15     {
    16         int i, j;
    17         for (i = 0; i < R; ++i)
    18         {
    19             for (j = 0; j < C; ++j)
    20             {
    21                 bool upwards;
    22                 cin >> upwards;
    23                 cookie[i][j] = upwards;
    24             }
    25         }
    26  
    27         // 在横向一共有2^R种变换
    28         int permute_r = 1 << R;
    29         int result = 0;
    30         for (i = 0; i < permute_r ; ++i)
    31         {
    32             // 完成当前的变换
    33             for (j = 0; j < R; ++j)
    34             {
    35                 // 这一行是否应当翻个面
    36                 if (i & (1 << j))
    37                 {
    38                     cookie[j].flip();
    39                 }
    40             }
    41             
    42  
    43             // 对每一列分别算出朝上和朝下的煎饼个数,取其最大值
    44             int possible_answer = 0;
    45             for (j = 0; j < C; ++j)
    46             {
    47                 int up_cookie_count = 0;
    48                 for (int k = 0; k < R; ++k)
    49                 {
    50                     if (cookie[k][j])
    51                     {
    52                         ++up_cookie_count;
    53                     }
    54                 }
    55                 possible_answer += max(up_cookie_count, R - up_cookie_count);
    56             }
    57             // 结果取最大值
    58             result = max(result, possible_answer);
    59             
    60             // 复原
    61             for (j = 0; j < R; ++j)
    62             {
    63                 if (i & (1 << j))
    64                 {
    65                     cookie[j].flip();
    66                 }
    67             }
    68         }
    69         cout << result << endl;
    70     }
    71  
    72     return 0;
    73 }

     ____________________总结的分割线____________________

    1. 原博有一个很妙的写法,permute = 2^N,循环 permute 次,每次又根据 (i & (1 << j)) 为真来确定特定要翻转的煎饼,这样,用二重循环加一个if判断就可以代替任意N重循环。【手动插入“你太强啦”表情包】
    2. bitset是个好东西,尖括号里写的不是数据类型,而是二进制的位数。
    3. 原博的写法是先定义了 int i,j ,以后的每次循环都直接用,和我的习惯不一样。我照着原博代码写的时候就发现了一个问题,经过测试如下:
       1 #include <iostream> 
       2 using namespace std;
       3 
       4 int main() {
       5     int i;
       6     for (i = 0; i < 3; i++) {
       7         for (i = 0; i < 5; i++) {
       8             cout << i;  //-->01234
       9         }
      10     }
      11     return 0;
      12 }
       1 #include <iostream> 
       2 using namespace std;
       3 
       4 int main() {
       5     for (int i = 0; i < 3; i++) {
       6         for (int i = 0; i < 5; i++) {
       7             cout << i; //-->012340123401234
       8         }
       9     }
      10     return 0;
      11 } 

      因此决定以后还是直接在for循环内定义变量,虽然麻烦点,但是减少了出错概率,以及不用想那么多变量名。

    2.1搜索的习题做完啦,开始做贪心^ ^

  • 相关阅读:
    【redis】--安全
    【redis】-- 数据备份和恢复
    2018.2.8 cf
    寒假零碎的东西 不定时更新补充.......
    hdu 1018
    2018寒假acm训练计划
    UVAlive 7466
    母函数
    简单数学题(水的不能在水的题了)
    随便写写的搜索
  • 原文地址:https://www.cnblogs.com/carolunar/p/6362550.html
Copyright © 2020-2023  润新知