题目链接
参考链接
由于只有代码…特别菜的我看了好久才明白,然后又打了一遍加了备注更容易看懂吧0 0
题意:两个教练选人,先找到当前队伍里能力值最大的人,然后选他和他左边的k个人和他右边的k个人(如果不够k个人则有多少选多少),1号教练先选,输出每个选手被哪个教练选走,被1选走输出1,被2选走输出2。
代码:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<algorithm>
using namespace std;
struct hh
{
int num;
int x;
};
bool cmp(hh k1,hh k2)
{
return k1.x<k2.x;
}
int pre[200005];
int next1[200005];
int ans[200005];
vector<hh>v;
int main()
{
int n,k;
scanf("%d%d",&n,&k);
int i,j,a;
for(i=1; i<=n; i++)
{
scanf("%d",&a);
v.push_back(hh{i,a});
}
sort(v.begin(),v.end(),cmp);
next1[0]=1;
for(i=1; i<=n; i++)
{
next1[i]=i+1;//下一个数
pre[i]=i-1;//上一个数
}
next1[n]=0;
int flag=1;
while(1)
{
if(next1[0]==0)
break;//next[0]==0说明在下面:next1[pre[id]]=next1[id]操作中id=n且pre[id]=0,说明所有数均被找完
int id=0;
for(i=v.size()-1; i>=0; i--)
{
if(ans[v[i].num]==0)
{
id=v[i].num;//id为当前最大数原来所在的位置
v.pop_back();
break;
}
else
v.pop_back();
}
int sum=0;
for(i=next1[id]; i!=0&&sum<k; i=next1[i]) //向右找k个
{
ans[i]=flag;
next1[id]=next1[i];//第i个数为当前被选定的数,选定完相当于没有了,所以它的下一个数可以理解为第id个数的下一个数
pre[next1[i]]=id; //当前被选定的前一个数可以看做第id个数
sum++;//当前向右找的数的个数
}
sum=0;
for(i=pre[id]; i!=0&&sum<k; i=pre[i]) //向左找k个
{
ans[i]=flag;
pre[id]=pre[i];//第i个数为当前被选定的数,选定完相当于没有了,所以它的上一个数可以理解为第id个数的上一个数
next1[pre[i]]=id;//当前被选的数的下一个数可以看做第id个数
sum++;//当前向左找的数的个数
}
ans[id]=flag;
next1[pre[id]]=next1[id];
pre[next1[id]]=pre[id];//第id个数被选过后,可以看做没有这个数
if(flag==1)
flag=2;
else
flag=1;
}
for(i=1; i<=n; i++)
printf("%d",ans[i]);
printf("\n");
}