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 }

浙公网安备 33010602011771号