题解:P13518 [KOI 2025 #2] 镜子
本题的关键在于:用所有
对称点计算
如果我在
- 若
a>b ,根据距离计算方法,我与镜子的距离是a-b ,对称后我在镜子左侧,位置是b-(a-b)=2b-a ; - 若
a<b ,同理,我与镜子的距离是b-a ,对称后我在镜子右侧,位置是b+(b-a)=2b-a ; - 若
a=b ,对称后的位置也是b=2b-b=2b-a 。
最终位置计算
现在,我们要将
设我第
那么对称后的位置就是
同时,又有
所以推出:
设第
现在来到了最关键的一步:观察正负号。
可以发现,上式中
然而,在
根据“负负得正”,
继续找规律可以发现这个结论:在
也就是说,对于所有的
此外,初始位置
- 若
N 是奇数,s 前符号是“- ”(因为第1 次s 前符号就是“- ”); - 若
N 是偶数,s 前符号是“+ ”。
位置最大值
现在题目要求最终位置
为了让这个值最大,我们要尽可能让大的数前面使用 “
由此我们也得到了排序的原则:从大到小,前
不要忘记乘上它们每个镜子前的系数
最后还要分情况讨论
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+5;
int n, s, a[N];
long long ans;
int main(){
cin >> n >> s;
for(int i=1; i<=n; i++)
cin >> a[i];
// 贪心 排序
sort(a + 1, a + n + 1, greater<int>());
// 正负号 统计答案
for(int i=1; i<=(n+1)/2; i++)
ans += a[i] * 2;
for(int i=(n+1)/2+1; i<=n; i++)
ans -= a[i] * 2;
// 分情况讨论
if(n % 2 == 0) ans += s;
else ans -= s;
cout << ans;
}