【贪心】Codeforces Round #436 (Div. 2) D. Make a Permutation!

题意:给你一个长度为n的数组,每个元素都在1~n之间,要你改变最少的元素,使得它变成一个1~n的排列。在保证改动最少的基础上,要求字典序最小。

预处理cnt数组,cnt[i]代表i在原序列中出现的次数。b数组,代表没有出现过的数是哪些。b数组的长度就是答案。

b数组是从小到大排好的,然后for循环b数组,同时用一个指针p指着a数组的当前位置,最开始指向开头,如果cnt[a[p]]==1,就向后跳,否则再看 是否b[i]<a[p]或者a[p]这个数是否已经出现过了(用个hav数组表示a[p]是否已经再前面出现过了)。只要满足这两个条件之一,就可以让cnt[a[p]]--,然后把a[p]修改为b[i]。如此一定能保证字典序最小。

#include<cstdio>
using namespace std;
int n,a[200005],cnt[200005];
bool hav[200005];
int b[200005],e;
int main(){
//	freopen("d.in","r",stdin);
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%d",&a[i]);
		++cnt[a[i]];
	}
	for(int i=1;i<=n;++i){
		if(!cnt[i]){
			b[++e]=i;
		}
	}
	int p=1;
	for(int i=1;i<=e;++i){
		while(cnt[a[p]]==1 || (!hav[a[p]] && b[i]>a[p])){
			hav[a[p]]=1;
			++p;
		}
		--cnt[a[p]];
		a[p]=b[i];
	}
	printf("%d\n",e);
	for(int i=1;i<n;++i){
		printf("%d ",a[i]);
	}
	printf("%d\n",a[n]);
	return 0;
}
时间: 2024-08-05 17:16:43

【贪心】Codeforces Round #436 (Div. 2) D. Make a Permutation!的相关文章

Codeforces Round #436 (Div. 2)【A、B、C、D、E】

Codeforces Round #436 (Div. 2) 敲出一身冷汗...感觉自己宛如智障:( codeforces 864 A. Fair Game[水] 题意:已知n为偶数,有n张卡片,每张卡片上都写有一个数,两个人每人选一个数,每人可以拿的卡片必须写有是自己选的数,问能否选择两个数使得两个人每人拿的卡片数一样多并且能拿光卡片.[就是看输入是不是只有两种数字] //:第一遍我看成字符串包含有选的数字也能拿,,这样写着居然过了..水题水题.. 1 #include<cstdio> 2

Codeforces Round #436 (Div. 2) C. Bus

Codeforces Round #436 (Div. 2) C. Bus A bus moves along the coordinate line Ox from the point x = 0 to the point x = a. After starting from the point x = 0, it reaches the pointx = a, immediately turns back and then moves to the point x = 0. After re

贪心 Codeforces Round #303 (Div. 2) B. Equidistant String

题目传送门 1 /* 2 题意:找到一个字符串p,使得它和s,t的不同的总个数相同 3 贪心:假设p与s相同,奇偶变换赋值,当是偶数,则有答案 4 */ 5 #include <cstdio> 6 #include <algorithm> 7 #include <cstring> 8 #include <cmath> 9 #include <iostream> 10 using namespace std; 11 12 const int MAX

贪心 Codeforces Round #191 (Div. 2) A. Flipping Game

题目传送门 1 /* 2 贪心:暴力贪心水水 3 */ 4 #include <cstdio> 5 #include <algorithm> 6 #include <cstring> 7 using namespace std; 8 9 const int MAXN = 1e2 + 10; 10 const int INF = 0x3f3f3f3f; 11 int a[MAXN]; 12 13 int main(void) //Codeforces Round #191

贪心 Codeforces Round #301 (Div. 2) B. School Marks

题目传送门 1 /* 2 贪心:首先要注意,y是中位数的要求:先把其他的都设置为1,那么最多有(n-1)/2个比y小的,cnt记录比y小的个数 3 num1是输出的1的个数,numy是除此之外的数都为y,此时的numy是最少需要的,这样才可能中位数大于等于y 4 */ 5 #include <cstdio> 6 #include <iostream> 7 #include <algorithm> 8 #include <cstring> 9 using na

贪心 Codeforces Round #297 (Div. 2) C. Ilya and Sticks

题目传送门 1 /* 2 题意:给n个棍子,组成的矩形面积和最大,每根棍子可以-1 3 贪心:排序后,相邻的进行比较,若可以读入x[p++],然后两两相乘相加就可以了 4 */ 5 #include <cstdio> 6 #include <algorithm> 7 #include <cstring> 8 #include <cmath> 9 using namespace std; 10 11 typedef long long ll; 12 13 co

贪心 Codeforces Round #135 (Div. 2) C. Color Stripe

题目传送门 1 /* 2 贪心:当m == 2时,结果肯定是ABABAB或BABABA,取最小改变量:当m > 2时,当与前一个相等时, 改变一个字母 3 同时不和下一个相等就是最优的解法 4 */ 5 #include <cstdio> 6 #include <cstring> 7 #include <algorithm> 8 using namespace std; 9 10 const int MAXN = 5e5 + 10; 11 const int IN

字符串处理/贪心 Codeforces Round #307 (Div. 2) B. ZgukistringZ

题目传送门 1 /* 2 题意:任意排列第一个字符串,使得有最多的不覆盖a/b字符串出现 3 字符串处理/贪心:暴力找到最大能不覆盖的a字符串,然后在b字符串中动态得出最优解 4 恶心死我了,我最初想输出最多的a,再最多的b,然而并不能保证是最多的:( 5 */ 6 #include <cstdio> 7 #include <cstring> 8 #include <string> 9 #include <iostream> 10 #include <

找规律/贪心 Codeforces Round #310 (Div. 2) A. Case of the Zeros and Ones

题目传送门 1 /* 2 找规律/贪心:ans = n - 01匹配的总数,水 3 */ 4 #include <cstdio> 5 #include <iostream> 6 #include <algorithm> 7 #include <cstring> 8 #include <cmath> 9 using namespace std; 10 11 const int MAXN = 2e5 + 10; 12 const int INF =