[cf1617C]Paprika and Permutation

Description

给定一个长度为n的数组,可以对任意一个数取模(除数自定义,无约束)。求最少需要几步可以使得数组变成n的排列。

Solution

首先对于一个数\(a_i\)取模,得到的结果范围在\([0,\lfloor\frac{a_i-1}{2}\rfloor]\)且这个范围内的自然数都可以取到。
显然,已经在[1,n]之中的数直接使用更优。
所以我们可以进行贪心,从小到大将还需要取模的每个数映射到剩余的[1,n]中即可。

#include<bits/stdc++.h>
using namespace std;
const int N=100005;
int a[N],s[N],t[N],n,m,n_s,n_t;
int main(){
	int ti;
	scanf("%d",&ti);
	while(ti--){
		scanf("%d",&n);
		for(int i=1;i<=n;++i)
			scanf("%d",&a[i]);
		sort(a+1,a+1+n);
		n_s=n_t=0;
		for(m=1;m<=n&&a[m]<=n;++m);
		for(int i=1;i<m;++i){
			if(a[i]==a[i-1]) s[++n_s]=a[i];
			else for(int j=a[i-1]+1;j<a[i];++j) t[++n_t]=j;
		}
		for(int i=m;i<=n;++i) s[++n_s]=a[i]; 
		for(int i=a[m-1]+1;i<=n;++i) t[++n_t]=i;

		int ans=0;
		for(int i=1;i<=n_t;++i){
			if(t[i]*2<s[i]) ++ans;
			else{
				ans=-1;break;
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}
posted @ 2022-03-22 17:14  Aireen_Ye  阅读(28)  评论(0编辑  收藏  举报
底部 顶部 留言板 归档 标签
Der Erfolg kommt nicht zu dir, du musst auf den Erfolg zugehen.