成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

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

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

[[411620]]

題目來源 AcWing[1]。

題目

你玩過“拉燈”游戲嗎?

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

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

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

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

我們用數(shù)字 表示一盞開著的燈,用數(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),編寫程序判斷游戲者是否可能在 步以內(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)無法使所有燈變亮,則輸出 。

數(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ì)需要說明:

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

因此:

  • 因?yàn)榘礋舻捻樞虿恢匾覀兛梢韵劝训谝恍械臒舳及戳?/li>
  • 我們發(fā)現(xiàn),第一行想按的燈都按過之后,如果想要讓第一行全亮,那么我第二行只能有一種按法,就是按第一行不亮的燈的下面的燈(下面是例子)
  1. 第一行狀態(tài) 10011 (1代表亮的燈) 
  2. 第二行動(dòng)作 01100 (1代表按按鈕) 

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

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

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

因此,對(duì)于任意一種輸入狀態(tài),我們把第一行 32 種按法全部遍歷一遍,看看哪些可以全亮(通過檢測(cè)第五行狀態(tà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)檩斎肓髅啃袥]有空格 
  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 來記錄 
  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.         // 以此類推,第二行定了后,第三行就被第二行決定了 
  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.         // 如果是有效的操作,咱看看一共按了幾次開關(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é)任編輯:武曉燕 來源: 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ǎ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)

主站蜘蛛池模板: 在线免费观看色 | 最新国产在线 | 欧美1区 | 亚洲aⅴ | 欧美舔穴 | 亚洲www啪成人一区二区 | 欧美aaaaa| 男女网站免费 | 91免费视频 | 国产激情偷乱视频一区二区三区 | 亚洲综合资源 | 网站黄色在线免费观看 | 波波电影院一区二区三区 | 国产大学生情侣呻吟视频 | 欧美成人精品在线 | 国产精品成人国产乱一区 | 二区国产 | 亚洲精品久久 | 精品国产乱码一区二区三区 | 婷婷精品 | 成人欧美一区二区三区黑人孕妇 | 国产日韩欧美另类 | 国产成人精品一区二区三区网站观看 | 国产成人精品一区二区三区视频 | 欧美精品日韩 | av黄色在线观看 | 精品久久一区 | 国产精品久久久久久久久久免费看 | 日本亚洲精品成人欧美一区 | www国产成人| 亚洲热在线视频 | 视频三区| 久久国产麻豆 | 狠狠av| 日韩一级精品视频在线观看 | 国产精品久久久久久久久久久久 | 一区二区免费高清视频 | 日韩av一区二区在线观看 | 在线播放国产一区二区三区 | 欧美中文字幕在线 | 91高清视频 |