日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

《算法竞赛进阶指南》打卡-基本算法-AcWing 95. 费解的开关:位运算、枚举、递推

發布時間:2025/4/5 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《算法竞赛进阶指南》打卡-基本算法-AcWing 95. 费解的开关:位运算、枚举、递推 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

      • 題目解答
      • 題目來源

題目解答


分析:

  • 枚舉第一行,指的是第一行哪些位置要切換狀態!!!。第一行總共有5個數,組合數是32,即第一行哪些位置要切換總共有32種情況。這就是我們的枚舉空間。比如,k = 0 表示第一行就這樣,不切換狀態。k = 2,二進制是 00010,就表示 數組g[][]的第一行第2個燈要切換狀態。

  • 這里的邏輯是:完成一件事A --> C ,拆分成兩步,先從A --> B ,再從B – >C ,總共需要的花費就是兩步之和。這里的A --> B 就是從g[][]變成第一行的新狀態,需要的反轉次數;這里的B – >C就是從第一行的新狀態開始往下翻轉,直到所有的燈都亮需要的反轉次數。

  • 采用的測試用例

    00111 01011 10001 11010 11100

    對了,這里對memcpy()函數稍作解釋
    memcpy(dest, src, 字節數),指的是把src數組復制到dest數組,并且需要指定字節數。

    比如

    memcpy(backup, g, sizeof g); // 把g數組復制到backup數組

    另外,這里解釋一下異或操作,在代碼中的體現是turn函數中用到了,把’0’變成’1’,把’1’變成’0’. 異或操作在配偶操作中很常見,是一種技巧,比如在求反向路徑的時候。

    char a = '0', b = a ^ 1;char c = '1', d = c ^ 1;cout << b << endl;cout << d << endl;/* 輸出為 1 0 */

    這里的過程是這樣的: ‘0’的Ascii值是48, 48 和1 異或(48的二進制表示是多少呢?然后如何求抑或呢?請讀者自行驗證。48 二進制: 110000 ,和1 異或得到 110001)得到的是49,正好是49,對應的字符是’1’.

    ac代碼

    #include<bits/stdc++.h> using namespace std; const int INF = 100000000;char g[10][10]; int dx[5] = {0, -1, 0, 1, 0}, dy[5] = {0, 0, 1, 0, -1};// 反轉燈 void turn(int x, int y){for(int i = 0; i < 5; i ++){int a = x + dx[i], b = y + dy[i];if( a >= 0 && a < 5 && b >=0 && b < 5){g[a][b] ^= 1;// 48 變成 49 即 '0'變成'1','1'變成'0'}} }int work(){int ans = INF;// 枚舉第一行哪些需要切換狀態!// 第一行共有32種狀態for(int k = 0; k < 1 << 5; k ++){int res = 0; // 統計翻轉次數char backup[10][10];memcpy(backup, g, sizeof g); // g數組copy到backup數組中// 把g[][]數組按照枚舉的第一行狀態進行更改// 如果k的某一位為1,表示g[][]數組第一行的這些位要切換狀態!// 然后依次往下遞推,以便找到最少的步數。for(int j = 0; j < 5; j ++){if( k >> j & 1){res ++;turn(0, j);}}//逐行遞推for(int i = 0; i < 4; i++)for(int j = 0; j < 5; j++){if( g[i][j] == '0'){res ++;turn(i + 1 , j);}}// 看最后一行是否全1bool is_successful = true;for(int i = 0; i< 5; i ++)if(g[4][i] == '0'){is_successful = false;break;}if(is_successful) ans = min(ans, res);memcpy(g, backup, sizeof backup);}if( ans > 6) ans = -1;return ans; }int main(){int T;cin >> T;while( T --){for(int i = 0; i < 5; i ++) cin >> g[i];cout << work() << endl;} }

    題目來源

    https://www.acwing.com/problem/content/97/

    總結

    以上是生活随笔為你收集整理的《算法竞赛进阶指南》打卡-基本算法-AcWing 95. 费解的开关:位运算、枚举、递推的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。