Karte
· 阅读需 4 分钟
[COCI 2017/2018 #5] Karte
Details
题目描述
有 张牌叠在一起,第 张牌上,有一个数字 表示它下面至少有 张牌上的信息是错误的,若它下面确实有至少 张牌的信息是错误的,那这张牌的信息就是正确的,否则这张牌的信息就是错误的。(我们认为最下面的牌的后面有 张错误的)
现在需要你重新调整牌的顺序,使得正好有 张牌上的信息是错误的。
输入格式
第一行两个正整数 和 表示牌的张数和要求的错误信息的个数。 接下来 行,每行一个数,表示对应的
输出格式
如果调整方案不存在,输出。否则输出由顶部到底部 张牌对应的 ,若有多种方案,输出任意一种即可。
输入输出样例 #1
输入 #1
4 2
1 2 2 3
输出 #1
2 3 1 2
输入输出样例 #2
输入 #2
5 3
2 1 3 0 3
输出 #2
3 3 0 1 2
输入输出样例 #3
输入 #3
6 4
0 2 5 2 0 1
输出 #3
-1
说明/提示
的数据 。
另有的数据 。
样例 2 说明:
第 张牌上写的是,但是其后面只有 张错误,所以它是错误的。
第 张牌上写的是,其后面有 张错误(第五张),所以它是正确的。
第 张牌上写的是,其后面有 张错误(第五张),所以它是正确的。
第 张牌上写的是,但是其后面只有 张错误(第五张),所以它是错误的。
第 张牌上写的是,但是其后面只有 张错误(第五张,第二张),所以它是错误的。
因此总共有 张是错误的。
分析
首先我们发现越大的数越难满足限制,所以我们不妨让它们非法而让其他的合法
贪心的想,我们尽量将较大的值放在非法位(前个),其他放在后面就行了
如何才能非法呢,我们从最大的数开始向下枚举,只要满足就是合法的了
而且放不了大的肯定也放不了小的,于是排序后线性扫描
时间复杂度:
AC代码
Code
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair< int,int >
#define QWQ return 0;
#define QAQ return
const int N=5e5+10;
int a[N];
int main()
{
// freopen( "1.in","r",stdin );
// freopen( "1.out","w",stdout );
ios::sync_with_stdio( false );
cin.tie( nullptr ); cout.tie( nullptr );
int n, k;
cin>>n>>k;
for( int i=1;i<=n;i++ ) cin>>a[i];
sort( a+1,a+n+1 );
queue< int > q;
for( int i=n;i>=1 && k;i-- )
if( a[i] >= k || k == 1 ) q.push( a[i] ), k--;
else { cout<<-1; QWQ; }
stack< int > stk;
for( int i=n-q.size();i>=1;i-- )
if( a[i] > q.size() ){ cout<<-1; QWQ; }
else stk.push( a[i] );
while( !stk.empty() ) cout<<stk.top()<<" ", stk.pop();
while( !q.empty() ) cout<<q.front()<<" ", q.pop();
QWQ
}
