LuoguP5016 [NOIP2018 普及组] 龙虎斗 题解
听说CSP前发题解会\(RP++\)?
纪念我\(CSP2019\)前最后一篇题解。
这题是\(NOIP2018\)普及组的第二题,我当时才刚学\(OI\)不到八个月,写出了个这样奇葩的代码:
#include <cstdio>
#include <cmath>
using namespace std;
int main() {
int n,c[100002],m,p1,s1,s2,p2;
float a[100002];
scanf("%d",&n);
for(int i=1; i<=n; ++i)
scanf("%d",&c[i]);
scanf("%d%d%d%d",&m,&p1,&s1,&s2);
int l=0,h=0;
for(int i=1; i<m; ++i)
l+=c[i]*(m-i);
for(int i=m+1; i<=n; ++i)
h+=c[i]*(i-m);
if(s1<m) l+=s1*(m-p1);
else if(s1>m) h+=s1*(p1-m);
if(l<h) {
for(int i=1; i<m; ++i)
a[i]=abs((m-i)-m/(float)s2);
p2=1;
for(int i=2; i<m; ++i)
if(a[i]<a[p2])
p2=i;
} else {
for(int i=m+1; i<=n; ++i)
a[i]=abs((i-m)-m/(float)s2);
p2=m+1;
for(int i=m+2; i<=n; ++i)
if(a[i]<a[p2])
p2=i;
}
printf("%d",p2);
return 0;
}
(不要吐槽我以前的码风qwq)
结果只有\(36\)分。
今天我一看的时候我就疯了:我那时真傻,这题哪要用除法,直接暴力模拟轻松搞定啊:)
于是我决定今天无论如何都要做这道题目。
结果,一开始\(4\)分,这让我很是尴尬,改了一些细节的错误之后,终于到了——\(64\)分。
我这才发现两个问题:
\(1)\) 要是这个天降空兵空降到了分界兵营里面呢?
\(2)\) 要是无论如何都不能将差值缩小呢?
其实这两个问题都好解决,并且都是一个问题,都可以归化到\(2)\)这个问题上去。
我们先枚举完加入某个兵营的最小差值,然后判断这是否比原来的差值还要大,如果是这样就要将他们放入分界兵营里面,谁也不干涉谁,否则按照原样处理即可。
不多说了,上代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
#define ll long long
ll n, s1, s2, p1, c[100007], ans, m, d, t, p2 = 9223372036854775807; //牢记去年不开long long见祖宗的教训
inline ll read() {
ll f = 1, x = 0;
char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar();
}
return x * f;
}
int main() {
n = read();
for(ll i = 1; i <= n; ++i)
c[i] = read();
m = read(), p1 = read(), s1 = read(), s2 = read();
for(int i = 1; i < m; ++i) {
d += c[i] * (m - i);
if(i == p1) d += s1 *(m - i);
}
for(int i = m + 1; i <= n; ++i) {
t += c[i] * (i - m);
if(i == p1) t += s1 * (i - m);
}
// printf("%lld %lld\n", d, t);
if(d < t) {
for(int i = 1; i < m; ++i) {
if(abs((m - i) * s2 + d - t) < p2) {
p2 = abs((m - i) * s2 + d - t);
ans = i;
}
}
} else {
for(int i = m + 1; i <= n; ++i)
if(abs((i - m) * s2 + t - d) < p2) {
p2 = abs((i - m) * s2 + t - d);
ans = i;
}
}
if(p2 > abs(d - t)) {
printf("%lld", m);
return 0;
}
printf("%lld", ans);
return 0;
}

浙公网安备 33010602011771号