題目描述
有如圖這樣5*6一共30個會發光的按鈕(既是按鈕又是燈泡)。每個按鈕按下去,會改變它自身以及上下左右五個燈泡的亮滅(角上邊上就不是五個了)。
給定乙個初始狀態,求一種按鈕組合,使得這些按鈕按下去以後,所有燈都滅了。
輸入輸出格式
sample input
2sample output0 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 0
1 0 1 0 1 1
0 0 1 0 1 1
1 0 1 1 0 0
0 1 0 1 0 0
puzzle #1我做完這題目以後,發現網上好像大部分都說什麼高斯……這……什麼是高斯來著!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
puzzle #2
1 0 0 1 1 1
1 1 0 0 0 0
0 0 0 1 0 0
1 1 0 1 0 1
1 0 1 1 0 1
我是用狀態,也可以叫列舉做的……
其實這題目有乙個簡單的事實,那就是,如果你任意選擇把第一行的幾個按鈕按下並且不再動第一行,那麼不管第一行按完以後是什麼狀態,為了把第一行所有的燈滅掉,你必須把第二行對應著第一行亮燈的列按下去。之後,同樣,第一第二行按完以後,第三行也必須按第二行亮燈的對應列。這樣,你把五行都按完,可以保證前四行的燈都是滅的。你只需要再檢視一下第五行是不是都是滅的,就知道這個解是不是符合要求。
每行6個燈,從000000到111111也只有64個狀態。只要對第一行遍歷這6個狀態,就能找到這個問題的解了。
解題的時候,先求出0-63這些狀態對應改變本行的值,
比如狀態000001,按下最後乙個按鈕,對應本行的狀態為000011,會改變最後兩個燈。然而對於上下排,你狀態本身對應它會改變的燈。
利用異或計算狀態影響,0ms也是無壓力的。
#define for(x,y) for(int x = 0;x0)
if (j<5)
}t/=2;
} for(j,6)
cc.digits[j] %=2;
st[i] = 0;
for(j,6)
st[i] += pow((float)2,j)*cc.digits[j];
} cin>>nc;
for1(nn,nc)
mset(out);
for(i,64)
}if ((st[out[4]]^out[3]) == input[4])
printf("\n");
}break;
}} }
return 0;
}
POJ1222熄燈問題
問題描述 程式 思路1 列舉所有可能的開關狀態,對每個狀態計算下最後燈的情況,看是否都熄滅 每種按鈕有兩種狀態,一共有30個開關,那麼狀態數是2的30次方,太多不可取 思路2 如何減少列舉的數目呢?如果存在某個區域性,一旦這個區域性狀態被確定後,那麼剩餘其他部分的狀態只能 是確定的一種或者不多的n種...
POJ 1222 開關問題
題意 傳送門 poj 1222 題解列舉第一行的開關是否翻轉的狀態,此時決定 l0j l l0 j 的狀態的只有 l1j l l1 j 乙個開關,依次類推可以求出所有的開關翻轉狀態。對於列舉的每乙個狀態,判斷最後一行是否全零即可判斷該方案是否可行。include include include in...
poj 1222 (高斯消元)
1 高斯消元法求解 適用於01方矩陣的問題,不適用在解線性方程組中 首先介紹一下怎樣用高斯消元法解題!這個遊戲的名字叫做lights out。乙個板子上面有mxn個按鈕,按鈕也是燈。每次按下乙個按鈕,這個按鈕和它的上下左右相鄰按鈕將同時切換各自的亮滅狀態。給你乙個初始狀態,請給出一種方法,按某些按鈕...