E. Two Teams
题意:两个教练要从 n
个学生中选择队员,第一行输入 n, k
,代表学生的数量,和队员选择的范围,第二行输入每个学生的代码技能(1-n
且各不相同),每个教练从未属于任何队伍的学生中,先定位代码技能最高的学生,然后将这名学生以及他左边k
个学生,右边k
个学生归队,第一个教练先开始,输出n
个数,1
代表归于第一个教练的队伍,2
代表归为第二个教练的队伍。
思路(模拟链表):由题意可知,当学生归队之后相当于从未归队学生中删除,会影响到下一个定位最大值的k
范围的选择,我们可以将未归队的学生当作一条链表,每次教练的选择之后,将这些归队的学生从链表中删除,用数组模拟这个过程即可。这样想是因为链表的特点-插入删除比较方便快捷。
AC代码:
#include<bits/stdc++.h>
using namespace std;
#define IO ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define show(x) cout<<x<<endl;
#define show_(x) cout<<x<<" ";
#define showEnd(x) {cout<<x<<endl; return 0;}
#define showxy(x, y) cout<<x<<" "<<y<<endl;
typedef long long ll;
typedef pair<int, int> iip;
typedef pair<ll, ll> llp;
const int MAXN = 200005;
const int INF = 0x3f3f3f3f;
const int MOD = 998244353;
int i, j, n, k, flag[MAXN] = {0}, zt = 1, t, L[MAXN], R[MAXN], cnt[MAXN] = {0};
iip a[MAXN];
int main()
{
cin>>n>>k;
for(i = 1; i <= n; i++) {
cin>>a[i].first;
a[i].second = i;
L[i] = i-1;
R[i] = i+1;
}
sort(a+1, a+n+1, greater<iip>());
for(i = 1; i <= n; i++) {
int index = a[i].second;
if(flag[index]) continue;
flag[index] = zt;
int l = L[index];
t = k;
while(t-- && l > 0){
flag[l] = zt;
l = L[l];
}
int r = R[index];
t = k;
while(t-- && r <= n){
flag[r] = zt;
r = R[r];
}
zt = (zt == 1 ? 2 : 1);
R[l] = r;
L[r] = l;
}
for(i = 1; i <= n; i++) {
cout<<flag[i];
}
show("")
return 0;
}
``