CF-1556B - Take Your Places!

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";
	}
}

小结:

​ 这个题目贪心还是很妙的,有一个类似的题目:戳我

posted @ 2021-09-02 00:10  tyrii  阅读(60)  评论(0)    收藏  举报