題目描述
軒軒和凱凱正在玩一款叫《龍虎斗》的游戲,游戲的棋盤是一條線段,
線段上有 n 個兵營(自左至右編號1∼n),相鄰編號的兵營之間相隔 1 厘米,即棋盤為長度為n−1 厘米的線段。
i 號兵營里有c i位工兵。
軒軒在左側,代表“龍”;凱凱在右側,代表“虎”。
他們以 m 號兵營作為分界, 靠左的工兵屬於龍勢力,靠右的工兵屬於虎勢力,而第 m 號兵營中的工兵很糾結,他們不屬於任何一方。
一個兵營的氣勢為:該兵營中的工兵數×該兵營到m號兵營的距離;
參與游戲 一方的勢力定義為:屬於這一方所有兵營的氣勢之和。
游戲過程中,某一刻天降神兵,共有s 1位工兵突然出現在了 p1號兵營。
作為軒軒和凱凱的朋友,你知道如果龍虎雙方氣勢差距太懸殊,軒軒和凱凱就不願意繼續玩下去了。
為了讓游戲繼續,你需要選擇一個兵營 p2,並將你手里的 s2位工兵全部派往 兵營 p2,使得雙方氣勢差距盡可能小。
注意:你手中的工兵落在哪個兵營,就和該兵營中其他工兵有相同的勢力歸屬(如果落在 mm 號兵營,則不屬於任何勢力)。
輸入格式:
輸入文件的第一行包含一個正整數n,代表兵營的數量。
接下來的一行包含 n 個正整數,相鄰兩數之間以一個空格分隔,第 i 個正整數代 表編號為 i 的兵營中起始時的工兵數量 ci。
接下來的一行包含四個正整數,相鄰兩數間以一個空格分隔,分別代表 m,p1,s1,s2。
輸出格式:
輸出文件有一行,包含一個正整數,即 p2,表示你選擇的兵營編號。如果存在多個編號同時滿足最優,取最小的編號。
最開始的想法就是分段比較氣勢差,於是寫出了如下代碼
(答案錯誤68)C++代碼
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long n,suml=0,sumh=0,min,max=9223372036854775807,ans,sum1,sum2;
cin>>n;
long long a[n+1];
for(int i=1;i<=n;i++)
cin>>a[i];
long long m,p_1,s_1,s_2;
cin>>m>>p_1>>s_1>>s_2;
a[p_1]+=s_1;
for(int i=1;i<m;i++)
suml+=a[i];
for(int i=m+1;i<=n;i++)
sumh+=a[i];
for(int i=1;i<=n;i++)
{
sum1=suml;
sum2=sumh;
if(i<m)sum1+=(m-i)*s_2;
if(i>m)sum2+=(i-m)*s_2;
min=abs(sum1-sum2);
if(min<max){
max=min;
ans=i;
}
}
cout<<ans<<endl;
return 0;
}
於是我決定稍微更改一下思路
(答案錯誤68)C++代碼
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long n,suml=0,sumh=0,min,ans;
cin>>n;
long long a[n+1];
for(long long i=1;i<=n;i++)
cin>>a[i];
long long m,p_1,s_1,s_2;
cin>>m>>p_1>>s_1>>s_2;
a[p_1]+=s_1;
for(long long i=1;i<m;i++)
suml+=a[i];
for(long long i=m+1;i<=n;i++)
sumh+=a[i];
ans=m;
min=abs(suml-sumh);
for(int i=1;i<=n;i++)
{
if(abs(suml-sumh+s_2*(m-i))<min){
min=abs(suml-sumh+s_2*(m-i));
ans=i;
}
}
cout<<ans<<endl;
return 0;
}
結果還是錯誤,於是我去某谷網站尋找答案
結果發現……
(AC)C++代碼
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long n,suml=0,sumh=0,min,ans;
cin>>n;
long long a[n+1];
for(long long i=1;i<=n;i++)
cin>>a[i];
long long m,p_1,s_1,s_2;
cin>>m>>p_1>>s_1>>s_2;
a[p_1]+=s_1;
for(long long i=1;i<m;i++)
suml+=a[i]*(m-i);//這里計算氣勢的時候,明明按關系式寫的,卻玄學的錯了
for(long long i=m+1;i<=n;i++)
sumh+=a[i]*(i-m);//這里也是!!!
ans=m;
min=abs(suml-sumh);
for(int i=1;i<=n;i++)
{
if(abs(suml-sumh+s_2*(m-i))<min){
min=abs(suml-sumh+s_2*(m-i));
ans=i;
}
}
cout<<ans<<endl;
return 0;
}
所以,我懷疑,我第一次寫的也是這個問題
果然如此,於是我重新提交
於是……
(AC)C++代碼
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long n,suml=0,sumh=0,min,max=9223372036854775807,ans,sum1,sum2;
cin>>n;
long long a[n+1];
for(int i=1;i<=n;i++)
cin>>a[i];
long long m,p_1,s_1,s_2;
cin>>m>>p_1>>s_1>>s_2;
a[p_1]+=s_1;
for(int i=1;i<m;i++)
suml+=a[i]*(m-i);//還是這里
for(int i=m+1;i<=n;i++)
sumh+=a[i]*(i-m);//就是這里
for(int i=1;i<=n;i++)
{
sum1=suml;
sum2=sumh;
if(i<m)sum1+=(m-i)*s_2;
if(i>m)sum2+=(i-m)*s_2;
min=abs(sum1-sum2);
if(min<max){
max=min;
ans=i;
}
}
cout<<ans<<endl;
return 0;
}
我:“我還能怎樣,還能怎樣,還不是像父親一樣把你原諒”
Dev-C++:“……”
最后引用某谷網上的一句話:十年OI一場空,不開long long見祖宗。