1. 程式人生 > 其它 >洛谷P5932[POI1999]多邊形之戰(C++,博弈論)詳細解析+程式碼註釋

洛谷P5932[POI1999]多邊形之戰(C++,博弈論)詳細解析+程式碼註釋

洛谷P5932 [POI1999]多邊形之戰

題目連結


題目背景

多邊形之戰是一個雙人遊戲。

題目描述

遊戲在一個有 n 個頂點的凸多邊形上進行,這個凸多邊形的 n−3 條對角線將多邊形分成 n-2 個三角形,這 n−3 條對角線在多邊形的頂點相交。

三角形中的一個被染成黑色,其餘是白色。雙方輪流進行遊戲,當輪到一方時,他必須沿著畫好的對角線,從多邊形上切下一個三角形。切下黑色三角形的一方獲勝。

  • 注:如果連線一個多邊形中任意兩點的線段都完全包含於這個多邊形,則稱這個多邊形為凸多邊形。

輸入格式

第一行是一個整數 n。表示多邊形的頂點數,多邊形的頂點從 0 到 n-1 順時針標號。

接著的 n-2 行描述組成多邊形的三角形。第 i+1 行,\(1 \leq i \leq n-2\)

,有三個空格分隔的非負整數 a, b, c,它們是第 i 個三角形的頂點編號,第一個給出的三角形是黑色的。

輸出格式

唯一一行應包含一個單詞:

  • TAK,表示先走的一方有必勝策略。
  • NIE,表示先走的一方沒有必勝策略。

輸入輸出樣例

輸入 #1

6

0 1 2

2 4 3

4 2 0

0 5 4

輸出 #1

TAK

說明/提示

對於所有的資料,\(4 \le n \le 50000\)


題目分析

本題是博弈中的基礎題,解題關鍵在於如何判斷出獲勝方,獲勝取決於構造出多邊形中黑三角的位置,那麼就需要對黑三角所有可能出現的位置進行分類找到共性。

解題思路

可以將所有可能情況分為以下三類:

  1. 黑三角位於多邊形最外層,第一次就可以切掉,那麼先手直接獲勝。

  2. 黑三角有一條邊是多邊形的外層,這種情況遊戲進行到最後一定會出現如下情況,也就是說輪到誰切倒數第二塊三角形誰獲勝,那麼就很容易看出,這種情況下誰獲勝與三角形數量的奇偶性有關。

  3. 黑三角位於多邊形內部,這種情況遊戲進行到最後同樣會出現如2中所示情況,獲勝同樣與三角形數量的奇偶性相關。

程式碼

#include<iostream>
#include<algorithm>

using namespace std;

int n;
int a[3];
int x,y,z;

int main()
{
	cin>>n;
	cin>>a[0]>>a[1]>>a[2];	//黑色三角形頂點
	for(int i=0;i<n-3;i++)
		cin>>x>>y>>z;	//依照題目要求象徵性輸入一下,解決本題不需要 
	sort(a,a+3);
	if((a[2]==a[1]+1&&a[1]==a[0]+1)||(a[0]==0&&a[1]==1&&a[2]==n-1)||(a[0]==0&&a[1]==n-2&&a[2]==n-1))	//判斷三個頂點是否連續,連續則代表黑色三角形在邊上可以直接切
		cout<<"TAK";
	else
	{
		if(n&1) cout<<"NIE";	//黑三角不在外圍時通過奇偶判斷輸贏,n&1是位運算相當於判斷n%2==1
		else cout<<"TAK";
	}
	return 0;
}