Two Teams
题目链接:点我看题
题意: n n n 个人有编程能力 a i a_i ai,排成一行。两个教练 A A A 和 B B B,教练 A A A 先手,每一次选这一行中的最大编程能力的人,然后再向左右两选取 k k k 个人,不足 k k k 个则全部选取,选取了的人就离开。然后教练 B B B 做相同的操作。 输出 最后每个人属于的教练, A A A输出 1 1 1, B B B 输出 2 2 2.
思路:
- 考虑到每次都需要最大值,可以用 s e t set set 维护一个结构体(含 i d id id 和 a [ i ] a[i] a[i]),按 a [ i d ] a[id] a[id] 从大到小重载运算符,那么每次提取都是提取 b e g i n ( ) begin() begin()。
- 对于两边的 k k k 个人,同样的用 s e t set set 维护结构体,和上面的一样,重载是按 i d id id 从小到大,每一次都 l o w e r _ b o u n d lower\_bound lower_bound 获取 当前最大值的 i d id id 在 此 s e t set set 中的迭代器位置,然后分别往前、往后遍历,记录答案,删除即可。
- !!!值得注意的是:需要先存起来,然后删除,因为删除的同时,遍历,迭代器会变
- 具体细节最好看代码
Code:
#include<bits/stdc++.h>
#define debug(x) cout << "[" << #x <<": " << (x) <<"]"<< endl
#define pii pair<int,int>
#define clr(a,b) memset((a),b,sizeof(a))
#define rep(i,a,b) for(int i = a;i < b;i ++)
#define pb push_back
#define MP make_pair
#define LL long long
#define ull unsigned LL
#define ls i << 1
#define rs (i << 1) + 1
#define fi first
#define se second
#define ptch putchar
#define CLR(a) while(!(a).empty()) a.pop()
using namespace std;
inline LL read() {
LL s = 0,w = 1;
char ch = getchar();
while(!isdigit(ch)) {
if(ch == '-') w = -1;
ch = getchar();
}
while(isdigit(ch))
s = s * 10 + ch - '0',ch = getchar();
return s * w;
}
inline void write(LL x) {
if(x < 0)
putchar('-'), x = -x;
if(x > 9)
write(x / 10);
putchar(x % 10 + '0');
}
#ifndef ONLINE_JUDGE
clock_t prostart = clock();
#endif
const int maxn = 2e5 + 10;
int a[maxn];
struct xx{
int id,maxx;
bool operator < (const xx &A) const{
return A.maxx < maxx;
}
};
set<xx> se;
struct node{
int id,maxx;
bool operator < (const node &A) const{
return id < A.id;
}
};
set<node> have;
int ans[maxn];
int main() {
#ifndef ONLINE_JUDGE
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif
int n = read(),k = read();
for(int i = 1;i <= n;++ i){
a[i] = read();
se.insert(xx{i,a[i]});
have.insert(node{i,a[i]});
}
int who = 1;
vector<int> v;
while(!se.empty()){
v.clear();
int id = se.begin() -> id;
ans[id] = who;
se.erase(xx{id,a[id]});
auto pos = have.lower_bound(node{id,a[id]});
auto tmp = pos; ++ tmp;
int coun = 0;
while(tmp != have.end() && coun < k){
ans[tmp -> id] = who;
v.pb(tmp -> id);
++ tmp; ++ coun;
}
for(int i = 0;i < v.size();++ i){
have.erase(node{v[i],a[v[i]]});
se.erase(xx{v[i],a[v[i]]});
}
v.clear();
coun = 0;
pos = have.lower_bound(node{id,a[id]});
tmp = pos;
if(tmp != have.begin()){
-- tmp;
while(tmp != have.begin() && coun < k){
ans[tmp -> id] = who;
v.pb(tmp -> id);
-- tmp; ++ coun;
}
if(coun < k){
ans[have.begin() -> id] = who;
v.pb(have.begin() -> id);
}
for(int i = 0;i < v.size();++ i){
have.erase(node{v[i],a[v[i]]});
se.erase(xx{v[i],a[v[i]]});
}
}
have.erase(node{id,a[id]});
who = who == 1 ? 2 : 1;
}
for(int i = 1;i <= n;++ i)
write(ans[i]);
ptch('\n');
#ifndef ONLINE_JUDGE
cout << "time: " << 1.0 * (clock() - prostart) / CLOCKS_PER_SEC << " s" << endl;
#endif
return 0;
}