第一日每日八题第八题之

#include<bits/stdc++.h>

using namespace std;

#define INF 0x3f3f3f3f

#define ll long long

using namespace std;

const int N=2e5+10;

vector<int> g;//代表牌堆,存储每个堆的堆顶元素

int ans[N],sz[N],nex[N];//分别代表每个牌所在堆是第几次操作被清除的,所在堆打的牌数,此牌的下一个牌号

int main()

{

int i,j,k,w1,n;

cin>>n>>k;

memset(ans,-1,sizeof(ans));

for(i=1;i<=n;i++)

{

cin>>w1;

if(g.size()==0)//如果当前桌面上一张牌也没有

{

g.push_back(w1);//将当前牌插入堆中

sz[w1]=1;

j=0; //记录当前插入的堆为第0号堆 ,只要有牌就要标记当前的堆数

}

else//桌面上有牌

{

if(w1>g[g.size()-1])//vector堆里维护的牌是按照从大到小来的,若最近的牌大小比当前要插入的大则插入的牌一定会覆盖掉前面的某一张牌

{

g.push_back(w1);

sz[w1]=1;

j=g.size()-1;

}

else//当前牌需要插入并覆盖掉牌堆的某一张牌

{

j=upper_bound(g.begin(),g.end(),w1)-g.begin();//此处j等于从左往右遍历的第一个堆顶大于等于w1的,也就是w1要覆盖的堆

sz[w1]=sz[g[j]]+1;//当前堆的牌的个数等于找到的堆的牌的个数+1

nex[w1]=g[j];//当前牌成为新的堆顶,使得当前牌的下一张牌指向旧的堆顶

g[j]=w1; //将新的堆顶更新

}

}

if(sz[w1]==k)//当前堆达到了需要删掉的条件

{

int t=w1;

while(t)//遍历当前t所在的堆

{

ans[t]=i;//记录当前堆的每个数实在第几次操作中被删除

t=nex[t];//继续遍历t指向的下一张牌,而最后一张牌指向的nex一定位0此时遍历结束。

}

g.erase(g.begin()+j);//清楚当前所在堆

}

}

for(i=1;i<=n;i++)

{

cout<<ans[i]<<endl;

}

return 0;

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值