#include<bits/stdc++.h>
#include <climits>
using namespace std;
const int maxn = 2e5+10;
int num[maxn][2];int maxbe = 0;int mined = INT_MAX;
int main()
{
int n;cin >> n;int x;
for(int i = 1;i<=2*n;i++) {
cin >> x;
if(!num[x][0]) {
num[x][0] = i;
if(i>maxbe) {
maxbe = i;
}
}
else {
num[x][1] = i;
if(i<mined) {
mined = i;
}
}
}
long long sum = 0;
for(int i = 1;i<=n;i++) {
sum+=num[i][1] - num[i][0] - 1;
}
if(mined < maxbe) sum+= (maxbe-mined)*2;
cout << sum;
}
看没人写题解,所以来水一篇(,,・ω・,,),算是比较简单的思维题
首先,我们用一个二维数组存放任意一个数的两处位置,那么我们很容易发现,num[k][1] > num[k][0]恒成立
题目中,小红要交换一次达成最大权值,所以我们来思考什么方式可以达成最大权值
首先,我们考察三种可能,包裹,重叠以及相离,这些到底是什么意思,我下面会一一解释
包裹
小红只能交换一次,所以交换相同的数字没有意义,所以,交换的数字一定是不同的,而包裹则是其中的一种可能的数字排列方式,例如
1xxx2xxxx2xxx1
这时,如果我们尝试交换1和2,这就构成了包裹
这里,我们很容易发现,无论怎么交换,权值一定不变,所以当交换的两个数产生如此排列时,我们不应该交换
重叠
同理,重叠也是其中的一种方式,例如
1xxxx2xxx1xxx2
1和2之间有着部分重叠,同样,在这种情况下,交换要么不变,要么变小,所以没有意义,我们也不换
相离
同样,例如
1xxxx1xxx2xxxx2
1和2之间的空间毫无交集,在这种情况下,交换1的最后一位和2的第一位必定会增大
到这里,很明显,我们的任务变成了,寻找最大相离的情况,如果没有,不变,有,加上增长的,最后输出
代码实现
for(int i = 1;i<=2*n;i++) {
cin >> x;
if(!num[x][0]) {
num[x][0] = i;
if(i>maxbe) {
maxbe = i;
}
}
else {
num[x][1] = i;
if(i<mined) {
mined = i;
}
}
}
num[k][0]代表一个数字的第一位,num[k][1]代表一个数字的第二位
long long sum = 0;
for(int i = 1;i<=n;i++) {
sum+=num[i][1] - num[i][0] - 1;
}
if(mined < maxbe) sum+= (maxbe-mined)*2;
cout << sum;
maxbe 代表所有数字第一位的最大值,mined代表所有数字第二位的最小值,如果maxbe > mined 则其为最大相离,反之,则不存在相离,直接输出即可,这是这段代码的主逻辑
蒟蒻实力浅薄,各路大佬轻喷(≧∀≦)ゞ

京公网安备 11010502036488号