[第三场(2)]Karte

题目描述
你有一副共有N张牌的牌,在第i张牌上会有一个数字ai表示在这张牌下面至少一共有ai张牌上的信息是假的。接下来你需要对这副牌进行洗牌,使得这副牌当中,恰好有K张牌的信息是错误的。
输入格式
第一行输入两个数字N、K(1≤N≤5*105,0≤K≤N)。

接下来N行,每行输入一个数字,表示第i张牌上的数字ai(0≤ai≤5*105)
输出格式
如果不存在恰好K张牌上的信息是错误的情况,则输出-1,否则,将这副牌从上往下输出这N张牌上的所对应的ai。如果有多种答案,输出任意一种。
样例
样例输入1

4 2
1
2
2
3
样例输出1

2 3 1 2
样例输入2

5 3
2
1
3
0
3
样例输出2

3 3 0 1 2
样例输入3

6 4
0
2
5
2
0
1
样例输出3

-1
数据范围与提示
对于样例2:第5张牌后没有牌,所以他后面是错误的牌的数量应该是0,但他是2,所以这张牌是错误的。第4牌后面有1张牌是错误的(第5张),它上面写的是1,所以是正确的。第3张牌上写的是0,它后面有1张牌是错误的(第5张),所以它是正确的(题目说的是至少有,不是确定有)。第2张牌上面写的是3,但它后面只有一张是错误的(第5张)所以是错误的。第1张牌上写的是3,但它后面只有2张是错误的(第2张和第5张),所以是错误的。即一共有3张是错误的。

解题思路

首先我们确定一点,牌的值越小,错误率越低。
我们进行排序,我们把值比较大的放在后面,放k个。
但要保证这一堆全错,我们就将这一堆进行反转,因为越往后,牌是越少的,我们将小的放在后面,错误率会高。
然后在判断一下是否符合条件。如果倒数k + 1的值都大于k,那肯定不合格。
然后判断那一堆里面是否符合。很简单。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
int n,k,a[1000005];
int main(){
	scanf ("%d%d",&n,&k);
	for (int i = 1;i <= n;i ++)
		scanf ("%d",&a[i]);
	sort(a + 1,a + 1 + n);
	int l = n - k + 1,r = n;
	while (l < r){
		swap(a[l],a[r]);
		l ++;
		r --;
	}
	if (a[n - k] > k){
		printf("-1");
		return 0;
	}
	for (int i = n - k + 1;i <= n;i ++)
		if (a[i] < n - i - 1){
			printf("-1
");
			return 0;
		}
	for (int i = 1;i < n;i ++)
		printf("%d ",a[i]);
	printf("%d
",a[n]);
}
原文地址:https://www.cnblogs.com/lover-fucker/p/13566655.html