NOIP2010普及組 三國遊戲

題目OJ地址html

http://codevs.cn/problem/1129/算法

https://www.luogu.org/problemnew/show/P1199spa

題目描述 Description

小涵很喜歡電腦遊戲,這些天他正在玩一個叫作《三國》的遊戲。.net

在遊戲中,小涵和計算機各執一方,組建各自的軍隊進行對戰。遊戲中共有 N 位武將(N爲偶數且不小於4),任意兩個武將之間有一個「默契值」,表示若此兩位武將做爲一對組合做戰時,該組合的威力有多大。遊戲開始前,全部武將都是自由的(稱爲自由武將,一旦某個自由武將被選中做爲某方軍隊的一員,那麼他就再也不是自由武將了),換句話說,所謂的自由武將不屬於任何一方。code

遊戲開始,小涵和計算機要從自由武將中挑選武將組成本身的軍隊,規則以下:小涵先從自由武將中選出一個加入本身的軍隊,而後計算機也從自由武將中選出一個加入計算機方的軍隊。接下來一直按照「小涵→計算機→小涵→……」的順序選擇武將,直到全部的武將被雙方均分完。而後,程序自動從雙方軍隊中各挑出一對默契值最高的武將組合表明本身的軍隊進行二對二比武,擁有更高默契值的一對武將組合獲勝,表示兩軍交戰,擁有獲勝武將組合的一方獲勝htm

已知計算機一方選擇武將的原則是儘可能破壞對手下一步將造成的最強組合,它採起的具體策略以下:任什麼時候刻,輪到計算機挑選時,它會嘗試將對手軍隊中的每一個武將與當前每一個自由武將進行一一配對,找出全部配對中默契值最高的那對武將組合,並將該組合中的自由武將選入本身的軍隊。 下面舉例說明計算機的選將策略,例如,遊戲中一共有6個武將,他們相互之間的默契值以下表所示:blog

雙方選將過程以下所示:遊戲

小涵想知道,若是計算機在一局遊戲中始終堅持上面這個策略,那麼本身有沒有可能必勝?若是有,在全部可能的勝利結局中,本身那對用於比武的武將組合的默契值最大是多少?ip

假設整個遊戲過程當中,對戰雙方任什麼時候候均能看到自由武將隊中的武將和對方軍隊的武將。爲了簡化問題,保證對於不一樣的武將組合,其默契值均不相同it

輸入輸出格式
輸入格式:
共 N 行。
第一行爲一個偶數 N,表示武將的個數。
第 2行到第 N行裏,第i+1行有Ni個非負整數,每兩個數之間用一個空格隔開,表示 i號武將和 i+1,i+2,…,N 號武將之間的默契值(0≤默契值≤1,000,000,000)。

輸出格式:
共 1 或 2行。
若對於給定的遊戲輸入,存在可讓小涵獲勝的選將順序,則輸出 1,並另起一行輸出全部獲勝的狀況中,小涵最終選出的武將組合的最大默契值。若是不存在可讓小涵獲勝的選將順序,則輸出0。

輸入輸出樣例
輸入樣例#1:
6
5 28 16 29 27
23 3 20 1
8 32 26
33 11
12
輸出樣例#1:
1
32

輸入樣例#2:
8
42 24 10 29 27 12 58
31 8 16 26 80 6
25 3 36 11 5
33 20 17 13
15 77 9
4 50
19
輸出樣例#2:
1
77

說明
【數據範圍】
對於 40%的數據有 N≤10。
對於 70%的數據有 N≤18。
對於 100%的數據有 N≤500。

 

算法分析:

參考https://blog.csdn.net/yuyanggo/article/details/48739849

根據題目中計算機選擇武將的策略可知:對於任意一個武將 i ,假設與其默契最高的爲j,其次爲k,那麼小涵要想拿到(i,j)是不可能的,拿到(i,k)確實100%能夠拿到的。(由於只要小涵選了編號爲 i 的武將,計算機就會選擇編號j的武將。)同理,電腦想要拿到(i,j)與(i,k)都是不可能的。
也就是說:對於每一個武將 i ,小涵能拿到與其默契值次高的武將 k,而電腦是拿不到最高與次高的。
綜上,小涵有必勝策略,答案爲最大的次高默契值。

具體算法:對每個武將i,掃描其餘武將,尋找到該武將與別人合做的次高默契值max2,這個max2就是當前的答案。將當前答案與歷史最優答案比較尋找總體最優答案便可。

舉例子分析以下:

對於輸入樣例2中的例子,分析發現(7,2)和(7,5)分別爲7號武將與別人合做的最高、次高默契值。

小涵選擇7號武將後,計算機將當即根據小涵選擇的7號武將作出判斷選擇2號武將。(由於7號與其餘武將的最高默契值是80.)這就致使小涵沒法選中(7,2),可是這同時也形成計算機沒法擁有(7,2)組合。

雖然小涵沒法擁有(7,2)組合的武將,可是小涵能夠選擇5號,從而武將造成(7,5)組合。

在雙發都沒法擁有最高默契值組合(7,2)的狀況下,小涵擁有了具備次高默契值的組合(7,5),絕對就能夠贏計算機。

代碼以下:

 1 #include <stdio.h>
 2 int main()
 3 {
 4     int i,j,n,a[505][505]={0};
 5     int max1,max2,ans=-1;
 6     scanf("%d",&n);
 7     for(i=1;i<n;i++)//控制輸入n-1行數據 
 8     {
 9         for(j=i+1;j<=n;j++)//每行從第i+1個一直到第n個
10         {
11             scanf("%d",&a[i][j]);
12             a[j][i]=a[i][j];
13         } 
14     }
15     /*for(i=1;i<=n;i++)
16     {
17         for(j=1;j<=n;j++)
18             printf("%4d ",a[i][j]);
19         printf("\n");
20     }*/
21     for(i=1;i<=n;i++)//掃描i行數據 
22     {
23         max1=max2=0;
24         for(j=1;j<=n;j++)//尋找i號武將與別人合做的最高默契值max和次高默契值max2 
25         {
26             if(a[i][j]>max1) { max2=max1; max1=a[i][j]; ans=(max2>ans?max2:ans);  }
27             else if(a[i][j]>max2) {  max2=a[i][j]; ans=(max2>ans?max2:ans);  }
28         }
29     }
30     printf("1\n%d\n",ans);
31     return 0;
32 }
相關文章
相關標籤/搜索