传送门http://codeforces.com/contest/1154/problem/E
题意很简单,直接每次向左向右遍历,找k个未被选的位置即可。如果每次都通过rem来判断是否选择,次数太多容易TLE。由于被选后就相当于被删除了,自然而然的就想到了链表。
#include<bits/stdc++.h>
using namespace std;
typedef struct{
int key, loc;
}D;
typedef struct{
int now, next, prev;
}Node;
Node node[200010];//位置链表
vector <D> d;
int rem[200010];
bool cmp(D x, D y){
return x.key > y.key;
}
int main(){
int n, k, x, turn = 1;
D dd;
cin >> n >> k;
for(int i = 0; i < n - 1; i++) node[i].next = i + 1;
for(int i = 1; i < n; i++) node[i].prev = i - 1;
node[0].prev = node[n-1].next = -1;
for(int i = 0; i < n; i++){
cin >> x;
dd.key = x; dd.loc = i;
d.push_back(dd);
}
sort(d.begin(), d.end(), cmp);
for(int i = 0; i < n; i++){
if(rem[d[i].loc]) continue;
int now1, now2, now, cnt = 0, flag1 = 1, flag2 = 1, t1, t2;//flag1,2 标志 向左,右
now = now1 = now2 = d[i].loc;
while(cnt <= k && flag1 + flag2){
if(flag1){
rem[now1] = turn;
t1 = node[now1].prev;
if(t1 == -1) flag1 = 0;
else node[now1].prev = node[t1].prev;
now1 = t1;
}
if(flag2){
rem[now2] = turn;
t2 = node[now2].next;
if(t2 == -1) flag2 = 0;
else node[now2].next = node[t2].next;
now2 = t2;
}
cnt++;
}
if(now1 != -1) node[now1].next = now2;
if(now2 != -1) node[now2].prev = now1;
turn = 3 - turn;//换教练
}
for(int i = 0; i < n; i++) cout << rem[i];
return 0;
}
很简单的题,但昨晚一开始没用链表,没想清楚思路就开始做,导致debug加改思路用了1h,没能在比赛结束前AC......
打cf总是比赛一结束就AC,真是令人头秃