题目传送门
算法解析
注意,本题要全开 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;
}
提交记录
尾声
如果这篇博客对您(您的团队)有帮助的话,就帮忙点个赞,加个关注!
最后,祝您(您的团队)在 OI 的路上一路顺风!!!
┬┴┬┴┤・ω・)ノ ByeBye