CF-1556B - Take Your Places!
题目大意:
有n个数,每次操作可以交换相邻的两个数,问最少几次操作可以让奇偶分开,不可能则出-1 。
思路:
需要知道奇数偶数的数量,若差值超过1,则不可能。
不然就是有可能的。若奇数多,则奇数应该放在135的位置;奇数少,则奇数应该放在246的位置。一句话说就是数量少的被“包在里面”。
若奇数偶数一样多,则要135,246位置都走一遍,取较小值。
要注意的是奇数归位的同时,偶数自然归位!
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int N = 2*1e8+10;
ll a[100050];
ll f[100050];
inline ll read(){
ll ans = 0;
char c = getchar();
while (!isdigit(c))
c = getchar();
while (isdigit(c)){
ans = ans * 10 + c - '0';
c = getchar();
}return ans;
}
ll solve(){
memset(a,0,sizeof a);
memset(f,0,sizeof f);//存奇数下标
ll n = read(),num = 0;
for(int i = 1;i <= n; i++){
a[i] = read();
if(a[i] & 1){
f[++num] = i;
}
}
if(abs(n - num * 2) > 1)return -1;
ll ans1 = 0;
for(int i = 1 ; i <= num ; i ++){
ans1 += abs(f[i] - 2 * i + 1);//可以左右移动
}
ll ans2 = 0;
for(int i = 1 ; i <= num ; i ++){
ans2 += abs(f[i] - i * 2 );
}
if(num > n - num)return ans1;
else if(num < n - num)return ans2;
return min(ans1,ans2);
}
int main(){
ll T = read();
while(T -- ){
cout<<solve()<<"\n";
}
}
小结:
这个题目贪心还是很妙的,有一个类似的题目:戳我

浙公网安备 33010602011771号