TZOJ 5799 費解的開關

2021-10-02 09:16:52 字數 1801 閱讀 9089

你玩過「拉燈」遊戲嗎?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個字元。每組資料描述了乙個遊戲的初始狀態。各組資料間用乙個空行分隔。

對於30%的資料,n<=5;

對於100%的資料,n<=500。

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

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

300111

01011

10001

11010

11100

11101

11101

11110

11111

11111

01111

11111

11111

11111

1111132

-1一開始想到搜尋,但是無從下手。然後發現每一行的燈都可以通過下一行的燈來關,而且最優解一定是每個開關最多只能開一次。所以可以暴力列舉第一行燈的操作,次數為2^n次。而最後我們只需要檢測最後一行燈是不是合法就可以了。

#include

using

namespace std;

int n,m,mp[20]

[20],b[20]

[20];

int fnum,anum;

void

tranc

(int i,

int j)

//對操作的燈的四周的燈進行變化

intmain()

}int t=

1<< n;

anum=7;

//初值為7

for(

int l=

0;l) fnum=0;

int moven=l;

for(

int i=

1;i<=m;i++

)//對第一行的燈進行操作

bool flog=0;

for(

int i=

2;i<=n;i++

)//對剩下的幾行燈操作}if

(flog)

break;}

if(flog)

continue

;int j;

for(j=

1;j<=m;j++

)//判斷最後一行是否合法

if(j==m+

1&&fnumanum=fnum;}if

(anum>=7)

cout <<-1

<< endl;

else

}}

費解的開關

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

費解的開關

時間限制 1 sec 記憶體限制 128 mb 提交 狀態 題目描述 你玩過 拉燈 遊戲嗎?25盞燈排成乙個5x5的方形。每乙個燈都有乙個開關,遊戲者可以改變它的狀態。每一步,遊戲者可以改變某乙個燈的狀態。遊戲者改變乙個燈的狀態會產生連鎖反應 和這個燈上下左右相鄰的燈也要相應地改變其狀態。我們用數字...

費解的開關

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