智力題 博弈論

2021-09-24 10:34:01 字數 4499 閱讀 2408

案例一

塗色1:你要在乙個nxm的格仔圖上塗色,你每次可以選擇乙個未塗色的格仔塗上你開始選定的那種顏色。同時為了美觀,我們要求你塗色的格仔不能相鄰,也就是說,不能有公共邊,現在問你,在採取最優策略的情況下,你最多能塗多少個格仔?

給定格仔圖的長n和寬m。請返回最多能塗的格仔數目。

測試樣例:

1,2返回:1

通過繪圖,顯示是二分之一

class

paint};

//答案

class

paint

};

案例二

賽馬:作為乙個馬場的主人,你要安排你的n匹賽馬和另乙個馬場的n匹馬比賽。你已經知道了對方馬場的出戰表,即參加每一場的馬的強壯程度。當然你也知道你自己的所有馬的強壯程度。我們假定比賽的結果直接由馬的強壯程度決定,即更壯的馬獲勝(若相同則雙方均不算獲勝),請你設計乙個策略,使你能獲得盡量多的場次的勝利。

給定對方每場比賽的馬的強壯程度oppo及你的所有馬的強壯程度horses(強壯程度為整數,且數字越大越強壯)同時給定n,請返回最多能獲勝的場次。

測試樣例:

[1,2,3],[1,2,3],3

返回:2

方法1:這個題目解法,就是如果horse a存在大於未參賽的對方馬,那就跟對方最大的弱於a的馬比賽,勝場次+1;若a小於等於所有未參賽的對方馬,那就選擇未參賽的最大的馬比賽。田忌賽馬。

方法2: 這裡我們不用考慮弱馬戰對方強馬即平或輸的情況,我們只要考慮清楚怎樣獲得最大的贏的次數,剩下的不管怎麼樣,隨機排就可以。那,我們對雙方馬按戰力排序,逆序找到能夠贏的次數,之所以逆序找,是因為這樣能使該贏的馬贏得對方戰力最大的馬。跟方法1比,只是不用考慮弱馬了,時間複雜度也變為了o(n)。

#include

#include

#include

using

namespace std;

intwinmost

(vector<

int> oppo, vector<

int> horses,

int n)

if(oppo[j]

>max)}if

(tmp!=-1

)else

if(mi!=-1

)flag[max]=1

;}return c;

}int

main()

;int b=

; vector<

int>oppo;

vector<

int>horses;

oppo.

assign

(a,a+

sizeof

(a)/

sizeof

(int))

; horses.

assign

(b,b+

sizeof

(b)/

sizeof

(int))

; cout<<

winmost

(oppo,horses,oppo.

size()

);return0;

}

改進:

#include

#include

#include

using

namespace std;

//只需排好序,找到能夠賽贏的最大次數即可

intwinmost

(vector<

int> oppo, vector<

int> horses,

int n)

}return c;

}int

main()

;int b=

; vector<

int>oppo;

vector<

int>horses;

oppo.

assign

(a,a+

sizeof

(a)/

sizeof

(int))

; horses.

assign

(b,b+

sizeof

(b)/

sizeof

(int))

; cout<<

winmost

(oppo,horses,oppo.

size()

);return0;

}

案例三

你和你的朋友正在玩棋子跳格仔的遊戲,而棋盤是乙個由n個格仔組成的長條,你們兩人輪流移動一顆棋子,每次可以選擇讓棋子跳1-3格,先將棋子移出棋盤的人獲得勝利。我們知道你們兩人都會採取最優策略,現在已知格仔數目,並且初始時棋子在第一格由你操作。請你計算你是否能獲勝。

給定格仔的數目n(n為不超過300的正整數)。返回乙個整數,1代表能獲勝,0代表不能獲勝。

測試樣例:

3返回:1

分析,通過畫圖發現,當遇到四個格仔時,雙方共同努力,就會讓先走的那個人失敗。

class jump 

};

案例四

a與b做遊戲。 在乙個n*m的矩陣中的出發點是(1,m),終點是(n,1),規則是只能向左移動一格,向下一格或向左下移動一格,先走到終點的為winner。 a先走。

給定兩個整數n和m,請返回最後的獲勝者的名字(a或b)。

測試樣例:

5 3返回:b

分析;當m和n都是奇數時,先走a的必輸,因為在每個方向上都是後手b先到;那麼在其他情況時,a都能走一步(左或下),使b走時走時變成全奇數,這樣b必輸。

class game 

};

案例五

現在有乙個整數陣列,其元素值均為1-n範圍內的某個整數,現在你和你的朋友在玩乙個遊戲,遊戲的目的是把陣列清空,你們輪流操作,你是先手,每次操作你可以刪除陣列中值為某個數的元素任意多個(當然陣列中值為這個數的元素個數應大於等於你刪除的個數,且你至少要刪除乙個數)。最先把陣列清空的人獲得勝利。假設你們都採取最優策略,請你計算你能否獲得勝利。

給定乙個整數陣列a和元素個數n。請返回乙個整數,1代表你能獲勝,0代表你不能獲勝。

測試樣例:

[1,1,1]

返回:1

nim博弈,原型:n堆石子,每次只能拿其中一堆,可以拿走該隊中任意個石子(>=1),對於幾大堆石子,先手能否獲勝?

分析:如果是兩種數字每種個數相同,那麼先手取一種數字的x個,後手就能在另一種數字中取x,只要這樣,最終後手就會取得勝利;當兩種數字不同時,先手先取多的那種數字中多出來的部分,之後的情況就和上一種情況相同,這時先手獲勝;再看多種數字的情況,nim有個判斷方法:對每種數字個數異或的結果判斷,當異或結果為0時,稱為平衡狀態,為1,稱為不平衡狀態,不平衡時(1)先手勝,平衡時(0)後手勝。為什麼?

對每種數字的個數按二進位制轉化,每位上表示該種數字的乙個自劃分:

a=an,an-1,...,a2,a1,a0;   

b=bn,bn-1,...,b2,b1,b0;

c=cn,cn-1,...,c2,c1,c0;

d=dn,dn-1,...,d2,d1,d0;

...

舉個例子:a=15(1111),b=13(1101),c=3(0011),d=1(0001);

1 1 1 1   

1 1 0 1

0 0 1 1

0 0 0 1

res=a ^ b ^ c ^ d;結果為0,表示後手勝;

假如先手拿a-7:

1 0 0 0   

1 1 0 1

0 0 1 1

0 0 0 1

這時,已經不像兩種數字時後手直接複製操作就可以取勝,因為不能同時拿兩種數字,那後手怎麼拿能夠取勝呢?先找到不平衡的最大數,這裡是1101,結對對1101-x->1010就又保持了平衡。

1 0 0 0   

1 0 1 0

0 0 1 1

0 0 0 1

其他操作見圖

還有乙個疑問,為什麼初始平衡,一定是後手勝呢?雙方都在追求平衡,最後一定會剩下兩個不一樣的數,還都是單個的,平衡的,先拿的肯定輸;再回過頭看,每次操作都都是平衡到不平衡,或者是不平衡到平衡,從最開始的平衡到最後的平衡,一定是經歷偶數次的,拿最後的平衡一定還是先手拿,所以先手輸。同樣,一開始不平衡,先手只需經歷乙個操作使其變為平衡,接著是後手操作,就跟上述一樣了,所以後手輸,先手勝。

class clear 

i=j-1;

//跳到下乙個數字

res^=tmp;

}return res !=0;}};

博弈

博弈論(sg)簡單題

鐵子和順溜在學習了博弈論的sg函式之後,解決了很多很多博弈題,現在他們遇到了一道難題。給出乙個長度為 n 的數列,數列裡的每個元素都是個位數,這個數列的每乙個連續子數列都能生成 乙個十進位制數,對於子數列a l r 這個十進位制數的個位為a r 十位為a r 1 最高位 為a l 現在鐵子需要知道最...

求職面試 智力題 智力題彙總

25匹馬 5個跑道 找top3,要多少次比賽 top3 推廣 找top5 解答 最後拿完對局 請設計乙個遊戲 地面上擺放著若干顆石子,甲乙兩人輪流從中提取石子,每人每輪最少提取2顆,最多提取5顆,取到最後一顆石子者為勝 請設定這堆石子的顆數 至少50顆 使先手有必勝的策略,並說明你的策略 設定的石子...

博弈論 Nim博弈

1.nim博弈的起源很早,至於歷史我們就不再說了,直接說它的使用場景。1 依舊是兩個人博弈,但是物品時n堆,每一堆有ai個。2 每個人可以挑選一堆取走若干個,但是不能不取。3 最先取完所有物品的人獲勝。4 結論 所以堆的物品的數量異或起來是0,先手必敗。2.乙個nim博弈的例項 nim博弈。乍一看這...