P1196吃糖果遊戲解題報告

2021-04-23 09:41:23 字數 3738 閱讀 2913

name: p1196吃糖果遊戲 matrix67 第一次模擬賽 系列 

author:  goal00001111

date: 18-12-08 19:47

description:

描述 description    

matrix67和shadow正在做乙個小遊戲。

桌子上放著兩堆糖果,matrix67和shadow輪流對這些糖果進行操作。在每一次操作中,操作者需要吃掉其中一堆糖果,並且把另一堆糖果分成兩堆(可以不相等)留給對方操作。遊戲如此進行下去,糖果數會越來越少,最後必將出現這樣一種情況:某人吃掉一堆糖果後發現另一堆裡只剩一塊糖果不能再分了。遊戲規定此時該操作者吃掉最後這一塊糖果從而取勝。

這個遊戲是不公平的。對於任意一種初始狀態,總有一方有必勝策略。所謂有必勝策略是指,無論對方如何操作,自己總有辦法取勝。

matrix67和shadow將進行10次遊戲,每一次遊戲中總是matrix67先進行操作。matrix67想知道每一次遊戲中誰有必勝策略。

輸入格式 input format     

輸入資料一共10行,每行有兩個用空格隔開的正整數,表示一次遊戲開始時桌子上兩堆糖果分別有多少個。

對於50%的資料,這些正整數均不超過100;

對於70%的資料,這些正整數均不超過10 000;

對於100%的資料,這些正整數均不超過10 000位。

輸出格式 output format     

輸出十行字串。這些字串只能是"matrix67"或"shadow",它們表示對應的十行輸入資料中有必勝策略的一方。

請注意大小寫。

樣例輸入 sample input     

1 1

1 2

1 3

1 4

1 5

2 1

2 2

2 3

2 4

2 5樣例輸出 sample output     

matrix67

matrix67

matrix67

matrix67

matrix67

matrix67

shadow

shadow

matrix67

matrix67

題目分析:

解決這類題目的方法就是列舉討論。

假設現在輪到你吃,擺在你面前的是糖果堆a和b。當你吃完堆a後,b將決定你的命運:

如果b = 1:你就是那個最幸運的人;

如果b = 2或b = 3:你都只能自認倒霉,因為無論你怎麼分,都將有乙份是1;

如果b = 4:你該感到慶幸,因為4 = 2 + 2,你把燙手的山芋扔給了對方;

同樣的5 = 2 + 3,6 = 3 + 3,你總能立於不敗之地;

如果b = 7:你將在劫難逃!因為7 = 1 + 6 = 2 + 5 = 3 + 4。

分成7 = 1 + 6馬上告負;

分成7 = 2 + 5可以勉強堅持一輪,但對方吃掉2,把剩下的5分成2和3送給你,你就輸定了;

分成7 = 3 + 4,對方吃掉3,把剩下的4分成2和2,你也難逃厄運;

同樣的8 = 1 + 7 = 2 + 6 = 3 + 5 = 4 + 4,你可以預見自己失敗的命運了吧;

如果b = 9:勝利女神又偏向你了!因為9 = 2 + 7,無論對方吃掉哪乙個都不好分;

同樣的10 = 3 + 7 = 2 + 8,怎麼分你自己看著辦吧,別讓自己輸了就行。

現在發現了吧,如果b = [2, 3, 7, 8],你穩贏;b = [2, 3, 7, 8],你必輸。

對於大於10的情況,我們可以設a = [2, 3, 7, 8],b = [1, 4, 5, 6, 9, 10]。

觀察集合a和b,我們可以發現每個b元素都能寫成兩個a元素之和對10求餘的形式:

1 = (3 + 8) % 10; 4 = (2 + 2) % 10; 5 = (2 + 3) % 10; 6 = (3 + 3) % 10; 9 = (2 + 7) % 10; 10 = (3 + 7) % 10;

如果擺在你面前的兩個堆的數量都可寫為10 * i + a的形式,不管你吃掉哪一堆,留下的第二個數都是10 * i + a,這時你無論怎麼分,分出來的兩個數中肯定有乙個可寫為10 * i + b的形式,而10 * i + b = 10 * j + a + 10 * k + a,即兩個數的個位數字都是集合a中的數,

這樣經過一輪後,回到你手裡的還是兩個10 * i + a,你沒辦法贏。

另外一種情況:擺在你面前的兩個堆的數量都可寫為10 * i + b的形式,這樣不管你吃掉那一堆,都可以把剩下的一堆分成10 * i + b = 10 * j + a + 10 * k + a,這樣送給對方的是兩個10 * i + a,他輸定了。

最後一種情況:擺在你面前的乙個堆的數量寫為10 * i + a的形式,另乙個堆的數量寫為10 * j + b的形式,你把堆10 * i + a 吃掉,剩下的堆10 * j + b分成兩個10 * i + a,穩操勝券。

因此得出結論:如果兩個堆數量的個位數字都屬於集合a,先拿者matrix67必敗,否則matrix67勝。

說明:

演算法思想:數學分析,總結規律。

資料結構:字串(c++),集合(pascal)。

時間複雜度:o(1);

空間複雜度:o(1);

程式語言:分別用c++和pascal實現。

附註:雖然題目說輸入的是兩個正整數,但是「對於100%的資料,這些正整數均不超過10 000位。」,

所以千萬不要用整型資料型別,而要用字串,否則肯定越界。

c++語言使用乙個很長的條件語句來判斷正整數的個位數字是否屬於集合a,而pascal語言則利用集合輕鬆搞定。

乙個相似的題目:設有n根火柴,甲乙兩人依次從中取走1根或2根,不能多取,也不能不取。

規定誰取走最後一根火柴誰就是勝利者,請你分析什麼情況下先取者有必勝策略。

聰明的你想到答案了嗎?

c++**:

#include

using namespace std;

int main(int argc, char* argv)

else

}system("pause");

return 0;

}pascal**:

program p1196 (input, output);

varch, m, n : char;

i : integer;

begin

for i:=1 to 10 do

begin

read(ch);

while not (ch in ['0'..'9']) do

read(ch);

while ch in ['0'..'9'] do

begin

m := ch;

read(ch);

end;

read(ch);

while not (ch in ['0'..'9']) do

read(ch);

while ch in ['0'..'9'] do

begin

n := ch;

read(ch);

end;

if (m in ['2','3','7','8']) and (n in['2','3','7','8']) then

writeln('shadow')

else

writeln('matrix67');

end;

end.

vijos1196吃糖果遊戲

matrix67和shadow正在做乙個小遊戲。桌子上放著兩堆糖果,matrix67和shadow輪流對這些糖果進行操作。在每一次操作中,操作者需要吃掉其中一堆糖果,並且把另一堆糖果分成兩堆 可以不相等 留給對方操作。遊戲如此進行下去,糖果數會越來越少,最後必將出現這樣一種情況 某人吃掉一堆糖果後發...

hdu吃糖果解題報告

題目 吃糖果 中文題目 hoho,終於從speakless手上贏走了所有的糖果,是gardon吃糖果時有個特殊的癖好,就是不喜歡將一樣的糖果放在一起吃,喜歡先吃一種,下一次吃另一種,這樣 可是gardon不知道是否存在一種吃糖果的順序使得他能把所有糖果都吃完?請你寫個程式幫忙計算一下。input 第...

Vijos P1196吃糖果遊戲 組合遊戲

matrix67和shadow正在做乙個小遊戲。桌子上放著兩堆糖果,matrix67和shadow輪流對這些糖果進行操作。在每一次操作中,操作者需要吃掉其中一堆糖果,並且把另一堆糖果分成兩堆 可以不相等 留給對方操作。遊戲如此進行下去,糖果數會越來越少,最後必將出現這樣一種情況 某人吃掉一堆糖果後發...