#include
using
namespace std;
intgetbit
(char c,
int i)
//取c的第i位
void
setbit
(char
&c,int i,
int v)
//設定c的第i位為v
void
flip
(char
&c,int i)
//將c的第i位取反
void
outputresult
(int t,
char result)
//輸出結果
cout << endl;}}
intmain()
}for
(int n =
0; n <
64; n++
)//遍歷首行開關的64種狀態}if
(i <4)
light[i +1]
= light[i +1]
^ switchs;
//i+1行燈的狀態改變
switchs = light[i]
;//i+1行開關狀態就等於i行燈的狀態}if
(light[4]
==0)//最後一行燈全部熄滅了,方案可行}}
return0;
}
getbit、setbit、flip 函式所用到的位運算子在這篇部落格:python的複習筆記 第四節 有詳細說明
我先說明一下主要思路:
1、因為按開關的順序與最終結果是沒有影響的,所以**就按照從第一行開始按起
2、當按完了第一行的開關,其實第二行也已經間接確定了的,因為按第二行的開關是為了將第一行的燈全滅,同理第二行開關按完後第三行的開關也已經間接確定了,所以通過列舉第一行所有按的開關的所有結果,並判斷最後一行的燈是否全滅來確定正確的按法
引用(&)能將改變實參的同時形參也改變,比如setbit()函式
溫習memset()函式
memset函式按位元組對記憶體塊進行初始化,所以不能用它將int陣列初始化為0和-1之外的其他值
用法類似於:如果要把乙個char a[20]清零,是 memset(a,0,20*sizeof(char))
溫習memcpy()函式
原型:extern void *memcpy(void *dest, void *src, unsigned int count)
功能:從src所指記憶體區域複製count個位元組到dest所指記憶體區域
解釋一下main()函式的**:(一定要結合**和圖畫一起思考)
orilight 是用來存初始化燈的亮滅的(1、0 )
light 是用來存按了開關後的燈的亮滅的(1、0 )
result 是用來存 當前行每個位置有無按開關 的(1、0 )
switchs 是用來存 下一行每個位置有無按開關 的(1、0 )
先用 memset 初始化 orilight;
再用為orilight 陣列賦值;
再列舉 2
*6 (64)種第一行的開關情況;
然後用 memcpy 初始化 light(內容就是 orilight );
再用 switchs 儲存列舉的第一行的開關情況;
再用 result 對第一行開關情況儲存;
然後分析當前行每個位置被開關過後亮滅情況,並用 light 儲存;
下一行燈亮滅情況就是下一行的 orilight 與 經當前行 switchs 操作後的燈亮滅情況
最後用 switchs 儲存下一行開關情況(這個 switchs 要保證能使當前行的燈全滅),故這個 switchs 恰好與當前行 light 的內容相同(畫圖)
要是仔細看也許你會發現此**用位運算子的函式取的數其實是從右邊開始數起的,但這並不影響最終結果,因為改變 light 的亮滅與switchs 的順序無關。
而且我還發現了:遇到位運算子 無論是char型還是int型的數字都自動轉化為int的二進位制形式
列舉 熄燈問題
有乙個由按鈕組成的矩陣,5行6列,每按一次改變原來顏色 具體事例如下圖所示 請寫乙個程式,判斷需要按哪些按鈕,能夠是燈泡全部熄滅。相關問題細節不再重複 剛剛輸入 2 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 0 0 1 0...
熄燈問題 列舉
1 問題描述 有乙個由按鈕組成的矩陣,其中每行有6個按鈕,共 5行。每個按鈕的位置上有一盞燈。當按下乙個按鈕後,該按鈕以及周圍位置 上邊 下邊 左邊 右邊 的燈都會改變一次。即,如果燈原來是點亮的,就會被熄滅 如果燈原來是熄滅的,則會被點亮。在矩陣角上的按鈕改變 3盞燈的狀態 在矩陣邊上的按鈕改變 ...
列舉 熄燈問題
問題描述 有乙個由按鈕組成的矩陣,其中每行有6個按鈕,共5行。每個按鈕的位置上有一盞燈。當按下乙個按鈕後,該按鈕以及周圍位置 上邊 下邊 左邊 右邊 的燈都會改變一次。即,如果燈原來是點亮的,就會被熄滅 如果燈原來是熄滅的,則會被點亮。在矩陣角上的按鈕改變3盞燈的狀態 在矩陣邊上的按鈕改變4盞燈的狀...