列舉 OpenJudge 1222 熄燈問題

2021-08-07 21:37:51 字數 3383 閱讀 1845

有乙個由按鈕組成的矩陣,其中每行有6個按鈕,共5行。每個按鈕的位置上有一盞燈。當按下乙個按鈕後,該按鈕以及周圍位置(上邊、下邊、左邊、右邊)的燈都會改變一次。即,如果燈原來是點亮的,就會被熄滅;如果燈原來是熄滅的,則會被點亮。在矩陣角上的按鈕改變3盞燈的狀態;在矩陣邊上的按鈕改變4盞燈的狀態;其他的按鈕改變5盞燈的狀態。

在上圖中,左邊矩陣中用x標記的按鈕表示被按下,右邊的矩陣表示燈狀態的改變。對矩陣中的每盞燈設定乙個初始狀態。請你按按鈕,直至每一盞等都熄滅。與一盞燈毗鄰的多個按鈕被按下時,乙個操作會抵消另一次操作的結果。在下圖中,第2行第3、5列的按鈕都被按下,因此第2行、第4列的燈的狀態就不改變。

請你寫乙個程式,確定需要按下哪些按鈕,恰好使得所有的燈都熄滅。根據上面的規則,我們知道

1)第2次按下同乙個按鈕時,將抵消第1次按下時所產生的結果。因此,每個按鈕最多隻需要按下一次;

2)各個按鈕被按下的順序對最終的結果沒有影響;3)對第1行中每盞點亮的燈,按下第2行對應的按鈕,就可以熄滅第1行的全部燈。如此重複下去,可以熄滅第1、2、3、4行的全部燈。同樣,按下第1、2、3、4、5列的按鈕,可以熄滅前5列的燈。

5行組成,每一行包括6個數字(0或1)。相鄰兩個數字之間用單個空格隔開。0表示燈的初始狀態是熄滅的,1表示燈的初始狀態是點亮的。

5行組成,每一行包括6個數字(0或1)。相鄰兩個數字之間用單個空格隔開。其中的1表示需要把對應的按鈕按下,0則表示不需要按對應的按鈕。

0 1 1 0 1 0 

1 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

解題思路

1、閱題後通過提示資訊可知

①當按下乙個按鈕後,該按鈕以及周圍位置(上邊、下邊、左邊、右邊)的燈都會改變一次。即,如果燈原來是點亮的,就會被熄滅;如果燈原來是熄滅的,則會被點亮。②

第2次按下同乙個按鈕時,將抵消第1次按下時所產生的結果。因此,每個按鈕最多隻需要按下一次。③

各個按鈕被按下的順序對最終的結果沒有影響。④

對第1行中每盞點亮的燈,按下第2行對應的按鈕,就可以熄滅第1行的全部燈。如此重複下去,可以熄滅第1、2、3、4行的全部燈。同樣,按下第1、2、3、4、5列的按鈕,可以熄滅前5列的燈。

2、我們發現燈只有按下與不按下兩種情況。若我們要知道哪些燈需要按下哪些燈不需要按可以實現燈全部熄滅

這樣測試最大可以達到2^30次,這樣的測試無疑是費時的,我們應選擇採用更合理的方式來減少測試量。

3、通過題幹中提示④我們可以發現,每當有一行需要按下的燈確定後他下一行需要按下的燈也隨之可以被確定,由此我們可以得出,每當第一行的燈被確定後,所有燈將均會被確定。這樣我們便將原本需要的測試量2^30減小為2^6。

4、接下來我們應該思考用什麼來表示這些燈的滅與亮?首先我們可以想到的是用乙個二維陣列進行儲存,但這裡我較為推薦的是用char型別的一維陣列來儲存,因為用char型別的一維陣列不僅在空間上,而且在執行時間上,到比使用二維資料更優。每乙個char型別的字元均是由8位二進位制數組成的,這樣我們便可以使用位運算來改變其0和1的值。

5、這裡就涉及到如何將這些01串轉入char型別的陣列中,我們應該設計乙個函式。

char orilights[6] = ;           //orilights應設定在main函式外面,方便使用 

for (int i = 0; i < 5; i++)

}void set(char *c, int i, int s)

如此便可以將每一行的01串寫入每乙個char型別的字元中。

6、接著需要遍歷第一行按下與不按下的所有情況(2^6),這時我們乙個新建乙個char型別的陣列儲存orilights裡面的所有值。(若不採取這一種方式,在執行完第一次判斷後orilights裡面的值就會被改變,無法進行重新判斷)

char result[6] = ;                            //結果,寫下燈是否按下 

char g[6] = ; //複製orilights的陣列

for(char temp = 0; temp < 64; temp++)

result[0] = temp;

}

7、再來便可以依照提示④的方式對新陣列進行更改。

8、在執行完第五行後,遍歷整個新陣列,檢查是否值全為0,若是則列印出按下方式後return,若不是則返回迴圈重新判斷。

下面是源**:

#include#include#includeusing namespace std;

char orilights[6] = ; //orilights應設定在main函式外面,方便使用

char result[6] = ; //結果,寫下燈是否按下

char g[6] = ; //複製orilights的陣列

void set(char *c, int i, int s) //錄入每乙個位的燈滅情況

void switchs(char *c) //對測試下燈滅情況進行修改

else if(i == 0)

else

} }}

void change(int i, int j) //按提示4修改燈滅情況

else if(j == 0)

else

}}void input(char *c) //輸出結果

else

}}int main()

for (int i = 0; i < 5; i++)

}for(char temp = 0; temp < 64; temp++)

result[0] = temp;

switchs(&temp);

for(int i = 1; i < 5; i++)

}int nums = 0; //判斷最後每個字元的ascll碼的值是否為0,若是nums+1,當nums==5時表示在該情況下燈全滅

for(int i = 0; i < 5; i++)

}if(nums==5)

}} return 0;

}

Openjudge切割回文 pku t1

描述 阿福最近對回文串產生了非常濃厚的興趣。如果乙個字串從左往右看和從右往左看完全相同的話,那麼就認為這個串是乙個回文串。例如,abcaacba 是乙個回文串,abcaaba 則不是乙個回文串。阿福現在強迫症發作,看到什麼字串都想要把它變成回文的。阿福可以通過切割字串,使得切割完之後得到的子串都是回...

USB學習 列舉1

一 列舉過程 獲取裝置描述符。該過程只是粗要獲取usb裝置的預設管道最大包長度。在初始化的過程中,usb裝置使能所有的資料完成傳輸中斷。1.主機傳送setup令牌包 80 06 00 01 00 40 00 2.端點0暫存器相對應的setup位置位,表明收到setup令牌包,所傳輸的資料報被sir儲...

列舉 1 熄燈問題

題目描述 有乙個由按鈕組成的矩陣,其中每行有6個按鈕,共5行。每個按鈕的位置上有一盞燈。當按下乙個按鈕後,該按鈕以及周圍位置 上 下 左 右 的燈都會改變一次。即,如果燈原來是點亮的,就會被熄滅 如果燈原來是熄滅的,則會被點亮。在矩陣角上的按鈕改變3盞燈的狀態 在矩陣邊上的按鈕改變4盞燈的狀態 其他...