NOIP2018龍虎鬥
龍虎鬥 軒軒和凱凱正在玩一款叫《龍虎鬥》的遊戲,遊戲的棋盤是一條線段,線段上有 n個兵營(自左至右編號 1 ~ n),相鄰編號的兵營之間相隔 1 釐米,即棋盤為長度為n − 1 釐米的線段。i號兵營裡有ci位工兵。 軒軒在左側,代表“龍”;凱凱在右側,代表“虎”。 他們以 m 號兵營作為分界,靠左的工兵屬於龍勢力,靠右的工兵屬於虎勢力,而第 m號兵營中的工兵很糾結,他們不屬於任何一方。
一個兵營的氣勢為:該兵營中的工兵數 × 該兵營到 m號兵營的距離;參與遊戲一方的勢力定義為:屬於這一方所有兵營的氣勢之和。
下面圖 2 為 n = 6,n= 4 的示例,其中紅色為龍方,黃色為虎方:
遊戲過程中,某一刻天降神兵,共有 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 說明】
見問題描述中的圖 2。
雙方以 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。
/*
民間資料80分版
#include <cstdio>
#include <iostream>
#define LL_ long long
using namespace std;
const int MAXN_ = 100005;
void Read_(LL_ &wo_X) {
LL_ wo_F = 1;
wo_X = 0;
char wo_C = getchar();
while(wo_C < '0' || wo_C > '9') {
if (wo_C == '-') {
wo_F = -1;
}
wo_C = getchar();
}
while(wo_C >= '0' && wo_C <= '9') {
wo_X = (wo_X << 3) + (wo_X << 1) + wo_C - '0';
wo_C = getchar();
}
wo_X *= wo_F;
}
LL_ PutOut_(LL_ X) {
if (X < 0) {
X = (~X) + 1;
putchar('-');
}
if (X > 9) {
PutOut_(X / 10);
}
putchar(X % 10 + 48);
}
LL_ Fabs_(LL_ wo_X) {
if (wo_X < 0)
wo_X = (~wo_X) + 1;
return wo_X;
}
LL_ wo_N ,wo_A[MAXN_] ,wo_Index = 0,wo_M ,wo_P1 ,wo_s1,wo_s2 ,X_Sum = 0 ;
LL_ K_Sum = 0 ,MINN = 0x3f3f3f3f3f3f3f3f;
int main() {
// freopen("fight.in","r",stdin);
// freopen("fight.out","w",stdout);
Read_(wo_N);
for (LL_ i = 1 ; i <= wo_N ; i ++ ) {
Read_(wo_A[i]);
}
Read_(wo_M);
Read_(wo_P1);
Read_(wo_s1);
Read_(wo_s2);
wo_A[wo_P1] += wo_s1;
for (LL_ i = 1 ; i < wo_M ; i ++ ) X_Sum += wo_A[i] * (wo_M - i);
for (LL_ i = wo_M + 1 ; i <= wo_N ; i ++ ) K_Sum += wo_A[i] * (i - wo_M);
if(X_Sum < K_Sum) {
for (LL_ p = 1 ; p < wo_M ; p ++ ) {
if (Fabs_(Fabs_(X_Sum + (Fabs_(wo_M - p) * wo_s2)) - K_Sum) < MINN) {
MINN = Fabs_(Fabs_(X_Sum + (Fabs_(wo_M - p) * wo_s2)) - K_Sum);
wo_Index = p;
}
}
}
else if(X_Sum > K_Sum) {
for (LL_ p = wo_M + 1 ; p <= wo_N ; p ++ ) {
if (Fabs_(Fabs_(K_Sum + (Fabs_(wo_M - p) * wo_s2)) - X_Sum) < MINN) {
MINN = Fabs_(Fabs_(K_Sum + (Fabs_(wo_M - p) * wo_s2)) - X_Sum);
wo_Index = p;
}
}
}
PutOut_(wo_Index);
return 0;
}
*/
//正解
#include <cstdio>
const int N=1e5+5;
int n,m,p1;
long long c[N],s1,s2;
int main() {
//freopen("fight.in","r",stdin);
//freopen("fight.out","w",stdout);
scanf("%d",&n);
for(int i=1; i<=n; ++i) {
scanf("%lld",&c[i]);//輸入
}
scanf("%d %d %lld %lld",&m,&p1,&s1,&s2);
c[p1]+=s1;
long long sum=0,minn=1LL<<62;//預處理
for(int i=1; i<=n; ++i) {
sum+=(i-m)*c[i];//統計虎的氣勢
}
int ans=m;
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;//記錄下標
}
}
printf("%d\n",ans);//輸出結果
return 0;
}