偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

遞推算法:令人費(fèi)解的開(kāi)關(guān)『拉燈』

開(kāi)發(fā) 前端 算法
游戲者改變一個(gè)燈的狀態(tài)會(huì)產(chǎn)生連鎖反應(yīng):和這個(gè)燈上下左右相鄰的燈也要相應(yīng)地改變其狀態(tài)。

[[411620]]

題目來(lái)源 AcWing[1]。

題目

你玩過(guò)“拉燈”游戲嗎?

盞燈排成一個(gè) 的方形。

每一個(gè)燈都有一個(gè)開(kāi)關(guān),游戲者可以改變它的狀態(tài)。

每一步,游戲者可以改變某一個(gè)燈的狀態(tài)。

游戲者改變一個(gè)燈的狀態(tài)會(huì)產(chǎn)生連鎖反應(yīng):和這個(gè)燈上下左右相鄰的燈也要相應(yīng)地改變其狀態(tài)。

我們用數(shù)字 表示一盞開(kāi)著的燈,用數(shù)字 表示關(guān)著的燈。

下面這種狀態(tài)

  1. 10111 
  2. 01101 
  3. 10111 
  4. 10000 
  5. 11011 

在改變了最左上角的燈的狀態(tài)后將變成:

  1. 01111 
  2. 11101 
  3. 10111 
  4. 10000 
  5. 11011 

再改變它正中間的燈后狀態(tài)將變成:

  1. 01111 
  2. 11001 
  3. 11001 
  4. 10100 
  5. 11011 

給定一些游戲的初始狀態(tài),編寫(xiě)程序判斷游戲者是否可能在 步以內(nèi)使所有的燈都變亮。

輸入格式

第一行輸入正整數(shù) ,代表數(shù)據(jù)中共有 個(gè)待解決的游戲初始狀態(tài)。

以下若干行數(shù)據(jù)分為 組,每組數(shù)據(jù)有 行,每行 個(gè)字符。

每組數(shù)據(jù)描述了一個(gè)游戲的初始狀態(tài)。

各組數(shù)據(jù)間用一個(gè)空行分隔。

輸出格式

一共輸出 行數(shù)據(jù),每行有一個(gè)小于等于 的整數(shù),它表示對(duì)于輸入數(shù)據(jù)中對(duì)應(yīng)的游戲狀態(tài)最少需要幾步才能使所有燈變亮。

對(duì)于某一個(gè)游戲初始狀態(tài),若 步以內(nèi)無(wú)法使所有燈變亮,則輸出 。

數(shù)據(jù)范圍

輸入樣例:

  1. 00111 
  2. 01011 
  3. 10001 
  4. 11010 
  5. 11100 
  6.  
  7. 11101 
  8. 11101 
  9. 11110 
  10. 11111 
  11. 11111 
  12.  
  13. 01111 
  14. 11111 
  15. 11111 
  16. 11111 
  17. 11111 

輸出樣例:

  1. -1 

題解

首先有三點(diǎn)很重要的性質(zhì)需要說(shuō)明:

  • 如果按哪些燈確定了,那么按這些燈的順序不重要,無(wú)論什么順序,結(jié)果都是相同的
  • 我們沒(méi)有必要按一盞燈兩次及以上,因?yàn)?,按兩次,相?dāng)于沒(méi)按,按三次,相當(dāng)于按兩次+一次(也就是一次)

因此:

  • 因?yàn)榘礋舻捻樞虿恢匾?,我們可以先把第一行的燈都按?/li>
  • 我們發(fā)現(xiàn),第一行想按的燈都按過(guò)之后,如果想要讓第一行全亮,那么我第二行只能有一種按法,就是按第一行不亮的燈的下面的燈(下面是例子)
  1. 第一行狀態(tài) 10011 (1代表亮的燈) 
  2. 第二行動(dòng)作 01100 (1代表按按鈕) 

那么,我們?cè)趺幢WC第二行全亮呢?只能用第三行來(lái)解決!

那么,我們?cè)趺幢WC最后一行(第五行)全亮呢?沒(méi)法保證!

我們發(fā)現(xiàn),如果第一行按法確定了,那么接下來(lái)二三四五行的按法和能不能全亮就確定了。

因此,對(duì)于任意一種輸入狀態(tài),我們把第一行 32 種按法全部遍歷一遍,看看哪些可以全亮(通過(guò)檢測(cè)第五行狀態(tài)),這些全亮的種有沒(méi)有操作次數(shù)小于等于 6 的。有的話,就返回這個(gè)操作數(shù),否則就返回 -1 唄。

代碼

  1. #include <iostream> 
  2. #include <cstring> 
  3. #include <algorithm> 
  4. using namespace std; 
  5.  
  6. const int N = 5 + 5;   // 加上 5 更保險(xiǎn) 
  7. // 注意接收時(shí)用字符串更方便,因?yàn)檩斎肓髅啃袥](méi)有空格 
  8. char g[N][N];  // 記錄燈目前的情況 
  9.  
  10. // 上右下左中 
  11. int dx[5] = {0, 1, 0, -1, 0}; 
  12. int dy[5] = {1, 0, -1, 0, 0}; 
  13.  
  14. // 按第 x 行第 y 列,本身和上下左右五個(gè)燈都取反 
  15. void turn(int x, int y) 
  16.     for (int i = 0; i < 5; ++ i) 
  17.     { 
  18.         int a = x + dx[i], b = y + dy[i]; 
  19.         if (0 <= a && a < 5 && 0 <= b && b < 5) 
  20.             g[a][b] = g[a][b] == '1' ? '0''1'
  21.     } 
  22.  
  23. int work() 
  24.     int ans = 2e9; 
  25.     // 第一層循環(huán),把所有第一行按的情況都遍歷 
  26.     // k 是被壓縮了的狀態(tài),最小 0b00000 代表都不按, 
  27.     // 最大 0b11111 代表都按 
  28.      
  29.     // 備份,因?yàn)橄旅娴牟僮鲿?huì)改變 g 
  30.     char backup[N][N]; 
  31.     memcpy(backup, g, sizeof g); 
  32.  
  33.     for (int k = 0; k < (1 << 5); ++ k) 
  34.     { 
  35.         // 確保我們的 g 是輸入的 g 
  36.         memcpy(g, backup, sizeof backup); 
  37.  
  38.         // 當(dāng)?shù)谝恍袨?nbsp;k 時(shí),總操作次數(shù)是.. 
  39.         int res = 0;  // 用 res 來(lái)記錄 
  40.  
  41.         // 執(zhí)行 k (根據(jù) k 把第一行按了) 
  42.         for (int j = 0; j < 5; ++ j) 
  43.         { 
  44.             if (k >> j & 1) 
  45.             { 
  46.                 res ++; 
  47.                 turn(0, j); 
  48.             } 
  49.         } 
  50.          
  51.         // 第一行確定了,第二行就確定了 
  52.         // 因?yàn)橹挥泻侠聿僮鞯诙?nbsp;
  53.         // 才能把第一行全部點(diǎn)亮 
  54.         // 以此類(lèi)推,第二行定了后,第三行就被第二行決定了 
  55.         for (int i = 0; i < 4; ++ i) 
  56.         { 
  57.             for (int j = 0; j < 5; ++ j) 
  58.             { 
  59.                 if (g[i][j] == '0'
  60.                 { 
  61.                     res ++; 
  62.                     turn(i + 1, j); 
  63.                 } 
  64.             } 
  65.         } 
  66.  
  67.         // 上面的操作一定能保證前 4 行全亮 
  68.         // 但是第 5 行不一定全亮,第 5 行全亮,才是真正有效的操作 
  69.         bool success = true
  70.         for (int j = 0; j < 5; ++ j) 
  71.         { 
  72.             if (g[4][j] == '0'
  73.             { 
  74.                 success = false
  75.                 break; 
  76.             } 
  77.         } 
  78.          
  79.         // 如果是有效的操作,咱看看一共按了幾次開(kāi)關(guān) 
  80.         if (success) ans = min(res, ans); 
  81.     } 
  82.      
  83.     // 根據(jù)題意返回輸出值 
  84.     if (ans > 6) return -1; 
  85.     return ans; 
  86.  
  87. int main() 
  88.     int n; 
  89.     cin >> n; 
  90.     while (n -- ) 
  91.     { 
  92.         for (int i = 0; i < 5; ++ i) cin >> g[i]; 
  93.         printf("%d\n"work()); 
  94.     } 

參考資料

[1]

 

AcWing: https://www.acwing.com/

 

責(zé)任編輯:武曉燕 來(lái)源: Piper蛋窩
相關(guān)推薦

2022-06-10 08:37:45

微軟WindowsWindows 11

2014-11-17 18:23:35

云服務(wù)大數(shù)據(jù)

2010-12-15 17:25:59

Exchange Se

2011-08-02 13:16:36

Objective-C 語(yǔ)法 函數(shù)

2018-09-15 05:09:28

2009-09-11 09:18:17

ASP.NET MVC

2010-03-25 12:21:44

無(wú)線網(wǎng)絡(luò)掉線故障

2023-03-13 08:33:36

java邏輯準(zhǔn)確值

2013-02-27 09:16:34

2023-12-14 07:33:29

Edge瀏覽器微軟

2017-09-14 09:40:32

PythonUbuntu信號(hào)機(jī)制

2020-07-29 09:50:54

人工智能網(wǎng)絡(luò)安全技術(shù)

2024-08-08 16:17:29

2013-03-22 10:30:16

IT主管ITM云計(jì)算

2017-01-19 09:12:39

Apriori算法流程

2018-04-09 11:11:03

RGB臺(tái)式機(jī)主機(jī)

2025-04-21 06:53:57

2012-03-23 14:38:31

JavaScript

2011-06-15 10:20:50

Ubuntu 11.0

2015-08-19 16:14:10

云共享數(shù)據(jù)共享云存儲(chǔ)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)