题目描述
轩轩和凯凯正在玩一款叫《龙虎斗》的游戏,游戏的棋盘是一条线段,线段上有 个兵营(自左至右编号),相邻编号的兵营之间相隔厘米,即棋盘为长度为厘米的线段。号兵营里有位工兵。 下面图为的示例:
轩轩在左侧,代表“龙”;凯凯在右侧,代表“虎”。 他们以号兵营作为分界, 靠左的工兵属于龙势力,靠右的工兵属于虎势力,而第号兵营中的工兵很纠结,他们不属于任何一方。
一个兵营的气势为:该兵营中的工兵数 × 该兵营到号兵营的距离;参与游戏 一方的势力定义为:属于这一方所有兵营的气势之和。
下面图为,的示例,其中红色为龙方,黄色为虎方:
游戏过程中,某一刻天降神兵,共有位工兵突然出现在了号兵营。作为轩轩和凯凯的朋友,你知道如果龙虎双方气势差距太悬殊,轩轩和凯凯就不愿意继续玩下去了。为了让游戏继续,你需要选择一个兵营,并将你手里的位工兵全部派往兵营,使得双方气势差距尽可能小。
注意:你手中的工兵落在哪个兵营,就和该兵营中其他工兵有相同的势力归属(如果落在号兵营,则不属于任何势力)。
输入输出格式
输入格式:
输入文件的第一行包含一个正整数,代表兵营的数量。接下来的一行包含个正整数,相邻两数之间以一个空格分隔,第个正整数代 表编号为的兵营中起始时的工兵数量。接下来的一行包含四个正整数,相邻两数间以一个空格分隔,分别代表,,,。
输出格式:
输出文件有一行,包含一个正整数,即,表示你选择的兵营编号。如果存在多个编号同时满足最优,取最小的编号。
输入输出样例
输入样例#1:
6
2 3 2 3 2 3
4 6 5 2
输出样例#1:
2
输入样例#2:
6
1 1 1 1 1 16
5 4 1 1
输出样例#2:
1
说明
输入输出样例 1 说明】
见问题描述中的图。
双方以号兵营分界,有位工兵突然出现在号兵营。 龙方的气势为:
虎方的气势为:
当你将手中的 位工兵派往号兵营时,龙方的气势变为:
此时双方气势相等。
【输入输出样例 2 说明】
双方以号兵营分界,有位工兵突然出现在号兵营。
龙方的气势为:
虎方的气势为:
当你将手中的位工兵派往号兵营时,龙方的气势变为:
此时可以使双方气势的差距最小。
【数据规模与约定】
。
对于的数据,
另有的数据,
对于的数据,
对于的数据,
对于的数据,
思路
其实这一道题还是比较简单的。读到这里应该已经有人握紧拳头了
因为是要后面读入的,所以我是读入完后再一个语句算出和(带表左方的气势,带表右方的气势)(还有气势也可以用前缀和算,但当时没有想到),然后根据两个判断和公式即可求出。
#include<iostream>
#include<cstdio>
using namespace std;
long long n,m,k,a[10000005];
int main()
{
// freopen("fight.in","r",stdin);
// freopen("fight.out","w",stdout);
scanf("%lld",&n);
for(int i=1;i<=n;++i)
scanf("%lld",&a[i]);
long long x,y;
scanf("%lld%lld%lld%lld",&m,&x,&y,&k);
if(m==1 || m==n)//因为都大于0,所以如果在1或n就可以直接输出m
{
printf("%d",m);
fclose(stdin);
fclose(stdout);
return 0;
}
a[x]+=y;//把后来要加的加上
long long l=0,r=0;
for(int i=1;i<=n;++i)//算气势
{
if(i<m)l+=(long long)a[i]*(m-i);
else r+=(long long)a[i]*(i-m);
}
if(l<r)//如果右边的气势比左边大,把“救兵”放左边
{
long long t=m-((r-l)/k);//这个程序的精华
if((r-l)%k>k/2)t--;//精华#2,因为要算最近的,所以一波骚操作
printf("%lld",max(t,(long long)1));//防止超界
}
else
if(l>r)//如果左边的气势比右边大,把“救兵”放右边
{
long long t=m+((l-r)/k);//精华
if((l-r)%k>k/2)t++;//精华#2
printf("%lld",min(t,(long long)n));//防止超界
}
else
if(l==r)printf("%lld",m);//如有两边气势相同,就放在分界点
// fclose(stdin);
// fclose(stdout);
return 0;
}