NOIP2018复赛普及组第二题《龙虎斗》CA代码
1、题目
【题目描述】
轩轩和开开正在玩一款叫《龙虎斗》的游戏,游戏的棋盘是一条线段,线段上有n个兵营(自左至右编号1~n),相邻编号的兵营之间相隔1厘米,即棋盘为长度为n-1厘米的线段。i号兵营里有ci位工兵。
轩轩在左侧,代表“龙”;凯凯在右侧,代表“虎”。 他们以 m 号兵营作为分界, 靠左的工兵属于龙势力,靠右的工兵属于虎势力,而第 ? 号兵营中的工兵很纠结,他 们不属于任何一方。
一个兵营的气势为:该兵营中的工兵数 × 该兵营到 m 号兵营的距离;参与游戏 一方的势力定义为:属于这一方所有兵营的气势之和。
游戏过程中,某一刻天降神兵,共有 s1 位工兵突然出现在了p1号兵营。作为轩轩和凯凯的朋友,你知道如果龙虎双方气势差距太悬殊,轩轩和凯凯就不愿意继续玩下去了。为了让游戏继续,你需要选择一个兵营 p2,并将你手里的 s2位工兵全部派往 兵营p2,使得双方气势差距尽可能小。
注意:你手中的工兵落在哪个兵营,就和该兵营中其他工兵有相同的势力归属(如果落在 m 号兵营,则不属于任何势力)。
【输入描述】
输入文件的第一行包含一个正整数 n,代表兵营的数量。
接下来的一行包含 n 个正整数,相邻两数之间以一个空格分隔,第 i 个正整数代表编号为 i 的兵营中起始时的工兵数量 ci。接下来的一行包含四个正整数,相邻两数间以一个空格分隔,分别代表 m, p1, s1, s2。
【输出描述】
输出文件有一行,包含一个正整数,即 p2,表示你选择的兵营编号。如果存在多个编号同时满足最优,取最小的编号。
【输入样例 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
2、注意
- .变量和数组都要用long long类型
- 在计算差值时,一定要用绝对值
- 绝对值函数不可以计算long long类型
3、代码
#include<iostream>
#include<cstdio>
#include<math.h>
using namespace std;
long long c[100001]={0};
long long n,m,s1,p1,s2,p2=0,i,j,cpn=0,cph=0,cha=0,ct1=0,ct2=0,chaju=0;
long long myabs(long long a)
{
if(a<0)a=-a;
return a;
}
int main(void)
{
freopen("fight.in","r",stdin);
freopen("fight.out","w",stdout);
cin>>n;
for(i=1;i<=n;i++)
{
cin>>c[i];
}
cin>>m>>p1>>s1>>s2;
c[p1]+=s1;
for(i=1;i<=n;i++)
{
if(i!=m)
{
if(i<m)
{
cpn+=c[i]*(m-i);
}
else
{
cph+=c[i]*(i-m);
}
}
}
int aa=0;
if(cpn>cph)
{
cha=cpn-cph;
aa=1;
}
else
{
cha=cph-cpn;
aa=2;
}
chaju=1000000000000000000;
if(cha==0)
{
cout<<m<<endl;
fclose(stdin);
fclose(stdout);
return 0;
}
if(aa==2)
{
for(long long rr=1;rr<=m;rr++)
{
if(myabs(cha-s2*(m-rr))<chaju)
{
chaju=myabs(cha-s2*(m-rr));
p2=rr;
}
}
}
else if(aa==1)
{
for(long long rr=m;rr<=n;rr++)
{
if(myabs(cha-s2*(rr-m))<chaju)
{
chaju=myabs(cha-s2*(rr-m));
p2=rr;
}
}
}
cout<<p2<<endl;
fclose(stdin);
fclose(stdout);
return 0;
}