[NOIP 2018 T2]龙虎斗

【NOIP 2018】龙虎斗

题目描述

轩轩和凯凯正在玩一款叫《龙虎斗》的游戏,游戏的棋盘是一条线段,线段上有 n个兵营(自左至右编号 1 ~ n),相邻编号的兵营之间相隔 1 厘米,即棋盘为长度为n − 1 厘米的线段。i号兵营里有ci位工兵。

    下面图 1 为 n = 6 的示例:

 

轩轩在左侧,代表“龙”;凯凯在右侧,代表“虎”。 他们以 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

       初看此题第一反应就是把每个都枚举一遍,因为题目并没有强调兵营的大小是否为正,所以必须将每个点都枚举一遍,寻找双方差距最小的时候的值,此题数据量较小,暴力枚举就可以过,不需要高效的剪枝。

源码

#include
#include
#include
#include
#include
using namespace std;
long long n,m,p1,s1,s2,sum1,sum2,minn=(long long)1e+20,k,number;
struct ming
{
    long long c;//人数
    long long far;//离m点的距离
    long long air;//气势
}a[100005];//定义结构体,按兵营计数
void read(long long &x)//输入优化
{
    long long f=1;x=0;char s=getchar();
    while(s>'9'||s<'0'){if(s=='-') f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=(x<<3)+(x<<1)+s-'0';s=getchar();}
    x*=f;
}
void write(long long x)//输出优化
{
    if(x<0)
    {
        x=(~x)+1;
        putchar('-');
    }
    if(x>9)
        write(x/10);
    putchar(x%10+'0');
}
long long Fabs(long long x)//判断绝对值
{
    if(x<0)
        return -x;
    return x;
}
int main()
{
    read(n);
    for(long long i=1;i<=n;i++)
        read(a[i].c);
    read(m);read(p1);read(s1);read(s2);
    a[p1].c+=s1;//得到天降神兵的兵营人数增加
    for(long long j=1;j<=n;j++)
    {
        a[j].far=Fabs(j-m);//计算每个兵营离m点的距离
        a[j].air=a[j].far*a[j].c;//计算每个兵营的气势
        if(jm)
            sum2+=a[j].air;//计算虎方
    }
    if(sum1==sum2)
    {
        write(m);
        return 0; 
    }//如果双方气势一致则放在m营中
    k=0;//k赋初值
    while(km)
        {
            t=sum2+a[k].far*s2;
            t1=sum1;
        }//大于m时虎方增加
        if(Fabs(t-t1)

谢谢欣赏!!!

你可能感兴趣的:(------模拟------)