洛谷P5016龙虎斗
哎呀,最近有点懈怠了 没办法,初三是真的忙 我尽量 哭泣
—————————————————————————
懂的都懂,这道题是基本的枚举模拟练习
现在让我们来看看题
—————————————————————————
题目简述
轩轩和凯凯正在玩一款叫《龙虎斗》的游戏,游戏的棋盘是一条线段,线段上有 n个兵营(自左至右编号 1∼n),相邻编号的兵营之间相隔 1厘米,即棋盘为长度为 n−1 厘米的线段。i号兵营里有Ci 位工兵。 下面图 1 为 n=6 的示例:
轩轩在左侧,代表“龙”;凯凯在右侧,代表“虎”。 他们以 m 号兵营作为分界, 靠左的工兵属于龙势力,靠右的工兵属于虎势力,而第 m 号兵营中的工兵很纠结,他们不属于任何一方。
一个兵营的气势为:该兵营中的工兵数× 该兵营到 m 号兵营的距离;参与游戏 一方的势力定义为:属于这一方所有兵营的气势之和。
下面图 2 为 n = 6,m=4 的示例,其中红色为龙方,黄色为虎方:
游戏过程中,某一刻天降神兵,共有 s1 位工兵突然出现在了 p 1号兵营。作为轩轩和凯凯的朋友,你知道如果龙虎双方气势差距太悬殊,轩轩和凯凯就不愿意继续玩下去了。为了让游戏继续,你需要选择一个兵营 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
输出
2
例2
输入
6
1 1 1 1 1 16
5 4 1 1
输出
1
—————————————————————————
【数据规模与约定】
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。
对于 60% 的数据,n ≤ 100, Ci = 1, s1,s2 ≤ 100。
对于 80% 的数据,n ≤ 100, Ci,s1,s2 ≤ 100。
对于 100% 的数据,n≤105,Ci,s1,s2≤109
—————————————————————————
此时此刻我晓得,有同学已经被题劝退了,但是,不慌,让我来给你细细讲解
—————————————————————————
说明/提示
m:为分界的兵营号
p1:系统降兵兵营号
s1:系统降兵数
s2:可操控兵数
【输入输出样例 1 说明】
见问题描述中的图 2。
双方以 m=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 =1 号兵营时,龙方的气势变为:
14+2×(4−2)=18
此时双方气势相等。
【输入输出样例 2 说明】
双方以 m=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
此时可以使双方气势的差距最小。
—————————————————————————
解析
首先,输入是很简单的
int n;
typedef long long ll;
ll c[100005];
ll m,p1,s1,s2;
cin>>n;
for(int i=1;i<=n;i++){
cin>>c[i];
}
cin>>m>>p1>>s1>>s2;
因为有系统降兵,所以我们先加上系统所降的兵,在分别计算龙气,虎气。
c[p1]+=s1;
现在,终于到了计算的时候 \(** ^ **)/
一个兵营的气势为:该兵营中的工兵数× 该兵营到 m 号兵营的距离
ll ql=0,qh=0;
for(int i=1;i<=n;i++){
if(i<m){
ql+=(c[i]*(m-i));
}else if(i>m){
qh+=(c[i]*(i-m));
}
}
我们来看看龙,虎两气现有差值
ll mins=fabs(ql-qh);
这里的“fabs”函数用于求绝对值(记得加头文件“# include < cmath >”)
—————————————————————————
主要步骤
将我们要调配的小兵一 一调配至各兵营,调配后再比较前后差值绝对值的大小,将差值绝对值小的所调配的兵营号记录下来
ll p2=m;
for(int i=1;i<=n;i++){
ll newl=ql;
ll newh=qh;
if(i<m){
newl+=(m-i)*s2;
}else if(i>m){
newh+=(i-m)*s2;
}
if(fabs(newl-newh)<mins){
mins=fabs(newl-newh);
p2=i;
}
最后,输出一下差值最小所调配兵营号即可
cout<<p2;
—————————————————————————
最后,将全部代码奉上
#include <iostream>
#include <cmath>
using namespace std;
int n;
typedef long long ll;
ll c[100005];
ll m,p1,s1,s2;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>c[i];
}
cin>>m>>p1>>s1>>s2;
c[p1]+=s1;
ll ql=0,qh=0;
for(int i=1;i<=n;i++){
if(i<m){
ql+=(c[i]*(m-i));
}else if(i>m){
qh+=(c[i]*(i-m));
}
}
ll mins=fabs(ql-qh);
ll p2=m;
for(int i=1;i<=n;i++){
ll newl=ql;
ll newh=qh;
if(i<m){
newl+=(m-i)*s2;
}else if(i>m){
newh+=(i-m)*s2;
}
if(fabs(newl-newh)<mins){
mins=fabs(newl-newh);
p2=i;
}
}
cout<<p2;
return 0;
}
—————————————————————————
加油↖(^ ω ^)↗

浙公网安备 33010602011771号