POJ 1222 解題報告

2021-06-08 14:04:09 字數 1582 閱讀 1944

題目描述

有如圖這樣5*6一共30個會發光的按鈕(既是按鈕又是燈泡)。每個按鈕按下去,會改變它自身以及上下左右五個燈泡的亮滅(角上邊上就不是五個了)。

給定乙個初始狀態,求一種按鈕組合,使得這些按鈕按下去以後,所有燈都滅了。

輸入輸出格式

sample input

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 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

sample output

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個按鈕,按鈕也是燈。每次按下乙個按鈕,這個按鈕和它的上下左右相鄰按鈕將同時切換各自的亮滅狀態。給你乙個初始狀態,請給出一種方法,按某些按鈕...