NOIP2018 普及组 T2 龙虎斗

本文详细解析了洛谷题目P5016的传送门算法,涉及longlong类型处理,通过计算龙虎双方势力并动态更新最小差值来找到最优策略。代码展示了如何遍历数组并确定最优位置p2。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目传送门

洛谷 P5016 [NOIP2018 普及组] 龙虎斗

算法解析

注意,本题要全开 long long

本题就是在 n n n 个位置上全试一遍就可以了。

首先需要把第 p 1 p_1 p1 位置上的值加上 s 1 s_1 s1,然后算出龙方和虎方的势力,将最小值设为龙方势力减虎方势力的绝对值,将 p 2 p_2 p2 设为 m m m

c[p1] += s1;

for(int i = 1; i < m; ++i)
	a += c[i] * (m - i);

for(int i = m + 1; i <= n; ++i)
	b += c[i] * (i - m);

minn = fabs(a - b);
p2 = m;

然后就是枚举 n n n 个位置,然后算出更新后的龙方势力减去虎方势力的绝对值,如果比当前的最小值小,就更新答案。

for(int i = 1; i < m; ++i) {
	ll tmp_a = a + s2 * (m - i);
	if(fabs(tmp_a - b) < minn) {
		minn = fabs(tmp_a - b);
		p2 = i;
	}
}

for(int i = m + 1; i <= n; ++i) {
	ll tmp_b = b + s2 * (i - m);
	if(fabs(a - tmp_b) < minn) {
		minn = fabs(a - tmp_b);
		p2 = i;
	}
}

最后输出 p 2 p_2 p2 即可。

总代码

#include <cstdio>
#include <cmath>
#define N 100005
using namespace std;

typedef long long ll;

ll n;
ll c[N];
ll m, p1, s1, s2;
ll a, b;
ll minn;
ll p2;

void inp() {
	scanf("%lld", &n);
	
	for(int i = 1; i <= n; ++i)
		scanf("%lld", &c[i]);
	
	scanf("%lld%lld%lld%lld", &m, &p1, &s1, &s2);
}

void work() {
	c[p1] += s1;
	
	for(int i = 1; i < m; ++i)
		a += c[i] * (m - i);
	
	for(int i = m + 1; i <= n; ++i)
		b += c[i] * (i - m);
	
	minn = fabs(a - b);
	p2 = m;
	
	for(int i = 1; i < m; ++i) {
		ll tmp_a = a + s2 * (m - i);
		if(fabs(tmp_a - b) < minn) {
			minn = fabs(tmp_a - b);
			p2 = i;
		}
	}
	
	for(int i = m + 1; i <= n; ++i) {
		ll tmp_b = b + s2 * (i - m);
		if(fabs(a - tmp_b) < minn) {
			minn = fabs(a - tmp_b);
			p2 = i;
		}
	}
	
	printf("%lld\n", p2);
}

int main() {
	inp();
	work();
	
	return 0;
}

提交记录

AC 记录

尾声

如果这篇博客对您(您的团队)有帮助的话,就帮忙点个赞,加个关注!

最后,祝您(您的团队)在 OI 的路上一路顺风!!!

┬┴┬┴┤・ω・)ノ ByeBye

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值