輸入
5行組成,每一行包括6個數字(0或1)。相鄰兩個數字之間用單個空格隔開。0表示燈的初始狀態是熄滅的,1表示燈的初始狀態是點亮的。
輸出5行組成,每一行包括6個數字(0或1)。相鄰兩個數字之間用單個空格隔開。其中的1表示需要把對應的按鈕按下,0則表示不需要按對應的按鈕。
樣例輸入
0 1 1 0 1 01 0 0 1 1 1
0 0 1 0 0 1
1 0 0 1 0 1
0 1 1 1 0 0
樣例輸出
1 0 1 0 0 1題目解析:1 1 0 1 0 1
0 0 1 0 1 1
1 0 0 1 0 0
0 1 0 0 0 0
從題中描述可知,一共有30個燈,乙個燈只有兩種狀態(開 & 關)。因此,我們可以用搜尋回溯演算法來依次列舉。本題的解是唯一的,因此可以直接在燈全部熄滅後輸出結果。但是回溯搜尋演算法的最大缺點是容易超時。如本題,若依次列舉30個燈,最大列舉量可達到2^30次,顯然會超時。因此,我們可以只列舉第一排(或者第一列、最後一列、最後一排),來推算出其他的按鈕。我們可以在搜尋回溯的一次改變完成後,儲存結果,假設第一排的按鈕是正確的,那麼第一排可能會殘留一些開啟的燈,我們就可以用「for」推算第二排,因為第一排的按鈕已經固定了,所以要使第一排的燈全部熄滅,就只能按下第一排仍然開啟的燈的下方的按鈕(例:第一排:0 0 0 1 0 1,則第二排需按按鈕: 0 0 0 1 0 1)。第三排的推算同第二排。一直推算到第五排,這時燈的形式已經固定了。開始判斷,若全部熄滅,則輸出;若還有開啟的燈,則恢復變化之前的結果,進行下一次搜尋回溯。
程式樣例:
//openjudge 1.13 14
//2017#4#7 17:13
#include#include#includeint tot; //除錯時使用,可刪去
char light[25][25],end[25][25]; //燈的狀態;需按下的按鈕
bool finish() //判斷燈是否全部熄滅的函式
void op(int x,int y) //用於按下座標為[x][y]的按鈕時,燈的狀態 和 需按下的按鈕 兩個矩陣的改變
void print() //除錯用函式,可刪除
printf("\n");
}void search(int x) //搜尋回溯 注:注意「op」函式,裡面用的取反,則兩次改變後恢復原來值,所以儲存結果時是儲存的按下按鈕之後的結果
,send[25][25]={}; //用於儲存結果的陣列
for(int i=1;i<=2;i++)
if(x<=6)
for(int j=1;j<=6;j++) //推算第2排
if(light[1][j]) op(2,j);
for(int j=1;j<=6;j++) //推算第3排
if(light[2][j]) op(3,j);
for(int j=1;j<=6;j++) //推算第4排
if(light[3][j]) op(4,j);
for(int j=1;j<=6;j++) //推算第5排
if(light[4][j]) op(5,j);
if(finish()) //如果全部熄滅
return ;
}for(int m=1;m<=5;m++) //如果沒有完全熄滅,恢復結果
for(int n=1;n<=6;n++)
search(x+1); //下一次搜尋回溯
}}int main()
NOI 2 1 1813 熄燈問題 題解 C
不廢話了,直接上題。1813 熄燈問題 總time limit 1000ms memory limit 65536kb description 有乙個由按鈕組成的矩陣,其中每行有6個按鈕,共5行。每個按鈕的位置上有一盞燈。當按下乙個按鈕後,該按鈕以及周圍位置 上邊 下邊 左邊 右邊 的燈都會改變一次...
openjudge 數字統計
總時間限制 1000ms 記憶體限制 100000kb 描述輸入n個整數,統計每個數出現的次數.輸入 第一行是乙個整數n 1 n 1000 接下來n行每行乙個整數.輸出 第一行輸出總共有多少個不同的整數.接下來每行輸出乙個整數及這個整數出現的次數,用空格分隔.輸出的整數的順序與它們在輸入中第一次出現...
Openjudge 括號匹配
這個用了普通的迴圈,資料量不是很大的話效率還是不錯的,如果資料比較大的話,換別的方法可能效率會高一點。思路很簡單 以字串中是否還存在沒有匹配過的 作為這個字串已經處理完畢的標誌。1,讀入字串,並進行處理,把所有不是 和 的字元都轉換成空格。2,從開始掃瞄字串,如果掃瞄到 記錄 的位置,直到掃瞄到 3...