1. 程式人生 > >NOIP2018龍虎鬥,頗有感觸,一道除了long long別無他法的題(本人平生第一次發文章,多多包涵)

NOIP2018龍虎鬥,頗有感觸,一道除了long long別無他法的題(本人平生第一次發文章,多多包涵)

NOIP2018 龍虎鬥
時間限制: 1 Sec 記憶體限制: 256 MB
題目描述

軒軒和凱凱正在玩一款叫《龍虎鬥》的遊戲,遊戲的棋盤是一條線段,線段上有 n個兵營(自左至右編號 1 ~ n),相鄰編號的兵營之間相隔 1 釐米,即棋盤為長度為n − 1 釐米的線段。i號兵營裡有ci位工兵。

軒軒在左側,代表“龍”;凱凱在右側,代表“虎”。 他們以 m 號兵營作為分界,靠左的工兵屬於龍勢力,靠右的工兵屬於虎勢力,而第 m號兵營中的工兵很糾結,他們不屬於任何一方。

一個兵營的氣勢為:該兵營中的工兵數 × 該兵營到 m號兵營的距離;參與遊戲一方的勢力定義為:屬於這一方所有兵營的氣勢之和。

遊戲過程中,某一刻天降神兵,共有 s1 位工兵突然出現在了 p1 號兵營。作為軒軒和凱凱的朋友,你知道如果龍虎雙方氣勢差距太懸殊,軒軒和凱凱就不願意繼續玩下去了。為了讓遊戲繼續,你需要選擇一個兵營p2 ,並將你手裡的 s2 位工兵全部派往兵營 p2 ,使得雙方氣勢差距儘可能小。

注意:你手中的工兵落在哪個兵營,就和該兵營中其他工兵有相同的勢力歸屬(如果落在 m 號兵營,則不屬於任何勢力)。

輸入

輸入檔案的第一行包含一個正整數n,代表兵營的數量。
接下來的一行包含n個正整數,相鄰兩數之間以一個空格分隔,第i個正整數代
表編號為i的兵營中起始時的工兵數量 di 。
接下來的一行包含四個正整數,相鄰兩數間以一個空格分隔,分別代表m,p1 ,s1 ,s2 。

輸出

輸出檔案有一行,包含一個正整數,即 p2 ,表示你選擇的兵營編號。如果存在多個編號同時滿足最優,取最小的編號。

樣例輸入

(如果複製到控制檯無換行,可以先貼上到文字編輯器,再複製)

【輸入樣例 1】
6
2 3 2 3 2 3
4 6 5 2
【輸入樣例 2】
6
1 1 1 1 1 16
5 4 1 1

樣例輸出

【輸出樣例 1】
2
【輸出樣例 2】
1

提示

【輸入輸出樣例 1 說明】

雙方以 n = 4 號兵營分界,有 s1 = 5 位工兵突然出現在 p1 = 6 號兵營。

龍方的氣勢為:

2 × (4 − 1) + 3 × (4 − 2) + 2 × (4 − 3) = 14

虎方的氣勢為:

2 × (5 − 4) + (3 + 5) × (6 − 4) = 18

當你將手中的 s2 = 2 位工兵派往 p2 = 2 號兵營時,龍方的氣勢變為:

14 + 2 × (4 − 2) = 18

此時雙方氣勢相等。

【輸入輸出樣例 2 說明】

雙方以 n = 5 號兵營分界,有 s1 = 1 位工兵突然出現在 p1 = 4 號兵營。

龍方的氣勢為:

1 × (5 − 1) + 1 × (5 − 2) + 1 × (5 − 3) + (1 + 1) × (5 − 4) = 11

虎方的氣勢為:

16 × (6 − 5) = 16

當你將手中的 s2 = 1 位工兵派往 p2 = 1 號兵營時,龍方的氣勢變為:

11 + 1 × (5 − 1) = 15

此時可以使雙方氣勢的差距最小。

【資料規模與約定】

1 < m < n,1 ≤ p1 ≤ n。

對於20%的資料,n = 3, m = 2, ci = 1, s1,s2 ≤ 100。

另有20%的資料, n ≤ 10, p1 = m, ci = 1, s1,s2 ≤ 100。

對於20%的資料,n = 3, m = 2, ci = 1,s1,s2 ≤ 100。

對於60%的資料, n ≤ 100, ci = 1,s1,s2 ≤ 100。

對於80%的資料, n ≤ 100, ci,s1,s2 ≤ 100。

對於100%的資料, n ≤ 10^5, ci = 1, s1,s2 ≤ 10^9。

附上詳盡程式碼

/*  思路:
    本題直接採用統計加暴枚思想便可AC
    主要注意資料範圍以及模擬方法
    採用差值比較法 , 節約時間並簡化過程 ( 虎的氣勢與龍的氣勢的差 )
*/
 
#include <cstdio>
 
long long N = 0 , M = 0 , P1 = 0 , Ans = 0 , C [ 100005 ] = {  } , S1 = 0 , S2 = 0 , Sum = 0 , Minn = 1LL << 62;
   
//比賽必須初始化
   
//N : 兵營數量
//M : 中立兵營編號
//P1 : 天降神兵的兵營編號
//C : 每個兵營的士兵數量
//S1 : 天降神兵的數量
//S2 : "我"手裡有的兵
//Sum : 虎的氣勢與龍的氣勢的差
//Minn : 用於算出最小的氣勢 ( 相當於 2 的 62 次方 ) 
   
//讀入優化
void Read ( long long &X )// '&' 表示引用 , 在函式中改變了 X 的值就意味著在外面 X 的值也會被改變
{
    int F = 1;//標記正負 , 用於負數的輸入
    X = 0;//歸零 , 有可能傳進來時 X 沒有歸零
    char S = getchar (  );//開始讀入
    while ( S < '0' || S > '9' )//不是數字字元
    {
        if ( S == '-' )//不能直接把 F = -1 , 有可能輸入的不是 '-' 而是其他數字字元
        {
            F = ( ~ F ) + 1;//這個數是負數則改變 F , 出去時就能正確判斷正負
        }
        S = getchar (  );//繼續讀
    }
    while ( S >= '0' && S <= '9' )//是數字字元
    {
        X = ( X << 3 ) + ( X << 1 ) + S - 48;//每讀一位 * 10 , 為後一位留位置
        S = getchar (  );//繼續讀
    }
    X *= F;//改變正負
}
  
void Print ( int X ) // 輸出優化
{
    if ( X < 0 ) //如果 X 是負數
    {
        X = ( ~ X ) + 1;//將 X 變為 正數
        putchar ( '-' );//輸出 '-' 號
    }
    if ( X > 9 )//如果 X 不能一次輸出 ( 因為putchar一次只能輸出一位 )
    {
        Print ( X / 10 );//先輸出最後一位前面的數 ( 如果前面的數 > 10 也可以通過這個遞迴輸出 )
    }
    putchar ( X % 10 + 48 );//輸出個位 ( 加上 48 才變為字元 )
}
   
int main()
{
    //freopen ( "fight.in" , "r" , stdin );//比賽不能加上註釋
    //freopen ( "fight.out" , "w" , stdout );//比賽不能加上註釋 
    Read ( N );//輸入 N , 兵營數量
    for ( int I = 1 ; I <= N ; I ++ )//迴圈輸入 C [ I ] , 每個兵營的士兵數量
    {
        Read ( C [ I ] );
    }
    Read ( M );//輸入 M , 中立兵營編號 
    Read ( P1 );//輸入 P1 , 天降神兵的兵營
    Read ( S1 );//輸入 S1 , 天降神兵的數量
    Read ( S2 );//輸入 S2 , "我"手裡有的兵
    C [ P1 ] += S1; // 初始化 C [ P1 ] , 既增加 S1 個士兵
    for ( int I = 1 ; I <= N ; I ++ )//迴圈統計虎的氣勢與龍的氣勢的差
    {
        Sum += ( I - M ) * C [ I ];
    }
    for ( int I = 1 ; I <= N ; I ++ )//迴圈列舉每一個兵營
    {
        long long Now = Sum + ( I - M ) * S2;//把將兵派到這個兵營後虎的氣勢與龍的氣勢的差算出
        if ( Now < 0 )//如果虎的氣勢與龍的氣勢的差小於零 
        {
            Now = ( ~ Now );//將它變成正數方便比較 ( 因為最小差是虎的氣勢與龍的氣勢的差的絕對值 )
        }
        if ( Now < Minn )//尋找最優的軍營
        {
            Minn = Now;//改變最小值方便下次比較
            Ans = I;//儲存答案
        } 
    }
    Print ( Ans );//輸出結果 , 即兵營編號
    return 0;//比賽必加
}

//作為本次NOIP的第二道題,不算很難,但是long long真的沒有想到
//最為一名本次NOIP成功退役的人,這道題我只拿了80分
//所以資料範圍真的很重要啊,坑壞了不少人