Vijos P1197 費解的開關

2021-08-14 07:45:46 字數 1671 閱讀 5840

描述

你玩過「拉燈」遊戲嗎?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」。

樣例1樣例輸入1

3

00111

01011

10001

11010

11100

11101

11101

11110

11111

11111

01111

11111

11111

11111

11111

樣例輸出1

3

2-1

限制

各個測試點1s

**matrix67原創

逆推思想+bfs

首先,我們很容易就會想到通過 bf

s / df

s 計算該狀態到終狀態的步數是否小於6步,然而這個時間複雜度並不是很理想

然後我們又可以想到,從燈全亮的狀態進行6次操作,顯然對於這些狀態一定可以通過逆推的方式在6次操作之內推回全亮的狀態

所以,我們只要記錄狀態以及其步數就可以a掉此題了!!!

這裡我用了位運算(懶得開陣列和結構體記錄了……)

#include

#include

#include

#include

#include

using namespace std;

int t;

int ans[1

<<25],q[1<<18]; //第二個陣列為了省空間,就開到這麼大了,因為操作6次的狀態恰好比這個小一點

int readln()

int change(int

x,int

y)void bfs()

}}int main()

return

0;}

費解的開關(vijos1197)

演算法 搜尋 很經典的一道題,也是很考驗選手水平的一道題。本題總共有兩種方法 費解的開關 題目本身是乙個經典的廣搜問題,題目讀完後可以立即寫出乙個廣搜的程式。但是,這只能通過30 的小資料 當n 500時做500次普通的廣搜必然超時。或許,有人曾想過提高每一次廣搜的效率,比如採用雙向搜尋。連雙向搜尋...

費解的開關

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

費解的開關

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