Codeforces Round #552 (Div. 3) E. Two Teams ###K ###K //K

题目链接:https://codeforces.ml/contest/1154/problem/E

题意:有两个队伍1和2, 每次一个队伍选当前剩余的最大的数并且加上半径为k的范围内的数进自己的队伍,队伍1先手,求最后所有人的所属队伍

思路:考虑直接模拟,要nlogn的做法,而且题目给的是排列,那么考虑用set,直接用set操作 每个数的大小是实现不了的,因为set中是有序的,

想到set来存放 每个数的下标,要模拟的时候就半径为k的数都删掉即可,时间复杂度nlogn   因为不知道set红黑树是怎么实现的,所以不要边遍历的时候边删除

不然可能中途的it 发生变化导致错误,测试了一下样例不行    要拿vector把数都记录下来最后再一起删除

 

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define pb push_back
 5 const int mod=1e4;
 6 const int maxn=2e5+10;
 7 int n,k;
 8 int p[maxn];
 9 int mp[maxn];
10 int ans[maxn];
11 
12 
13 int main()
14 {
15     ios::sync_with_stdio(0);
16     cin.tie(0);
17     cin>>n>>k;
18     set<int>s;
19     set<int>max1;
20     for(int i=1;i<=n;i++)
21     {
22         int x;
23         cin>>x;
24         p[i]=x;
25         mp[x]=i;
26         s.insert(i);
27     }
28     max1=s;
29     vector<int>temp;
30     int f=2;
31     while(s.size())
32     {
33         temp.clear();
34         int u=*max1.rbegin();
35         int pos=mp[u];
36         auto it=s.find(pos);
37         temp.pb(pos);
38         auto it1=it;
39         auto it2=it;
40         for(int i=1;i<=k;i++)
41         {
42             it2++;
43             if(it2==s.end())
44                 break;
45             temp.pb(*it2);
46         }
47         for(int i=1;i<=k;i++)
48         {
49             if(it1==s.begin())
50                 break;
51             it1--;
52             temp.pb(*it1);
53         }
54         for(auto &v:temp)
55         {
56             int num=1+f%2;
57             ans[v]=num;
58             int val=p[v];
59             max1.erase(val);
60             s.erase(v);
61         }
62         f++;
63     }
64     for(int i=1;i<=n;i++)
65         cout<<ans[i];
66 
67     cout<<'\n';
68 
69 
70 
71 
72 }
View Code

 

posted @ 2020-08-09 20:05  canwinfor  阅读(118)  评论(0)    收藏  举报