演算法 費解的開關(遞推與遞迴)

2021-10-18 13:20:08 字數 1836 閱讀 9843

這題類似於我們玩過的乙個小遊戲。當按下中間按鈕時,這個按鈕及上下左右四個方向上的燈的開關轉換一次。本題要求我們將整個矩陣能否在6步以內點亮。

其實這個題的思路很「清奇」因為當我們將第一行的所有操作進行遍歷(共有2^5種情況)然後為了將第一行的燈全部點亮,故第二行的操作就能根據第一行燈的狀態唯一確定。以此類推就可以確定下面所有的操作。而且只用關心最後一行是否為亮,因為除了最後一行的位置一定是全亮的。

你玩過「拉燈」遊戲嗎?25盞燈排成乙個5x5的方形。每乙個燈都有乙個開關,遊戲者可以改變它的狀態。每一步,遊戲者可以改變某乙個燈的狀態。遊戲者改變乙個燈的狀態會產生連鎖反應:和這個燈上下左右相鄰的燈也要相應地改變其狀態。

我們用數字「1」表示一盞開著的燈,用數字「0」表示關著的燈。下面這種狀態

10111

01101

10111

10000

11011

在改變了最左上角的燈的狀態後將變成:

01111

11101

10111

10000

11011

再改變它正中間的燈後狀態將變成:

01111

11001

11001

10100

11011

給定一些遊戲的初始狀態,編寫程式判斷遊戲者是否可能在6步以內使所有的燈都變亮。

第一行輸入正整數n,代表資料中共有n個待解決的遊戲初始狀態。

以下若干行資料分為n組,每組資料有5行,每行5個字元。每組資料描述了乙個遊戲的初始狀態。各組資料間用乙個空行分隔。

一共輸出n行資料,每行有乙個小於等於6的整數,它表示對於輸入資料中對應的遊戲狀態最少需要幾步才能使所有燈變亮。

對於某乙個遊戲初始狀態,若6步以內無法使所有燈變亮,則輸出「-1」。

0300111

01011

10001

11010

11100

11101

11101

11110

11111

11111

01111

11111

11111

11111

1111132

-1

#include

using

namespace std;

int map[10]

[10];

int map1[10]

[10];

int dir[5]

[2]=

;void

turn

(int x,

int y)

else}}

intmain()

else

}getchar()

;}int cnt =26;

for(

int i =

0; i <32;

++i)

}for

(int j =

0; j <5;

++j)

if(i >> j &1)

for(

int j =

0; j <4;

++j)

for(

int k =

0; k <5;

++k)

if(map1[j]

[k]==-1

)int dark =0;

for(

int j =

0; j <5;

++j)}if

(dark ==0)

}if(cnt >6)

else

getchar()

;}return0;

}

原題鏈結

費解的開關(遞推)

題意 25盞燈排成乙個5x5的方形。每乙個燈都有乙個開關,遊戲者可以改變它的狀態。每一步,遊戲者可以改變某乙個燈的狀態。遊戲者改變乙個燈的狀態會產生連鎖反應 和這個燈上下左右相鄰的燈也要相應地改變其狀態。用數字 1 表示一盞開著的燈,用數字 0 表示關著的燈。下面這種狀態 10111 01101 1...

AcWing 95 費解的開關(遞推)

題目 include include include include using namespace std const int n 6 char g n n backup n n backup用於儲存,複製原陣列 int dx 5 dy 5 用於方位轉化 void turn int x,int y...

遞推 AcWing 95 費解的開關

思路 列舉第一行的所有情況 列舉完第一行後,固定住第一行,此時第二行按哪個按鈕是確定的。假設第一行某盞燈是0,那麼需要按第二行對應的燈泡來改變第一行。同理,操作第三行和第四行 遍歷第五行看看是否都為1。如果都為1,則達到目標。include include using namespace std c...