[关闭]
@AkamemakA 2022-07-21T05:23:36.000000Z 字数 1966 阅读 169

Atcoder 题解

Atcoder Beginner Contest 260 problem D题解


题目大意

题目链接:点我

桌面上有张背面朝上的牌,每张牌上有一个数字,包含了中的整数。你将会进行次翻牌操作。每次翻牌时,翻开最上面的一张牌,寻找在桌面上有无数字大于等翻开的数字的正面朝上的牌。若有,则把翻开的牌正面朝上,放在符合条件的牌中数字最小的牌上(覆盖它)。若没有,则把牌正面朝上,放在桌面上。若某时某刻,桌面上一堆正面朝上的牌中牌的数量,则吃掉这堆牌。对,输出牌上数字为的牌被吃掉时的操作数。做操做完后牌上数字为的牌没有被吃掉,则输出

输入个整数

样例输入1

  1. 5 2
  2. 3 5 2 1 4

样例输出1

  1. 4
  2. 3
  3. 3
  4. -1
  5. 4

样例解释1

由于没有被吃掉,第行应输出

样例输入2

  1. 5 1
  2. 1 2 3 4 5

样例输出2

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5

如果,那么所有的牌一放到桌子上就会被吃掉。

样例输入3

  1. 15 3
  2. 3 14 15 9 2 6 5 13 1 7 10 11 8 12 4

样例输出3

  1. 9
  2. 9
  3. 9
  4. 15
  5. 15
  6. 6
  7. -1
  8. -1
  9. 6
  10. -1
  11. -1
  12. -1
  13. -1
  14. 6
  15. 15

数据范围


解析

妥妥的模拟题。

我们用一个数组来存下当前所有正面朝上的牌堆中最上面的一张牌的数字。因为每一次放牌时,都是找到大于等于这个数的最小的那个数,如果这个数组满足单调性,那么显然在改变之后,数组仍然满足单调性。

因此,我们可以用中的容器来存储牌堆顶元素。会自动使元素满足单调递增性。因此,在寻找牌堆时,可以使用二分来查找。幸运的是,中自带_函数,帮助我们找到要操作的一堆牌。

另外在更新数组时,由于中只存下了牌顶元素,不知道牌堆中有哪些元素。因此,我们可以另开一个数组,表示数字为的那张牌下的那张牌数字为。如果这张牌是最底下的那一张,则可以为任何数。

然后,我们就可以向下求出这一堆牌中的所有元素。(见下)

  1. for(int j=0;j<k;j++){
  2. res[x]=i;
  3. x=under[x];
  4. }

(第一次写时用的是,不知道怎么删除元素就枚举所有牌堆,了四个点(悲伤))


代码实现

  1. #include<iostream>
  2. #include<cstring>
  3. #include<set>
  4. using namespace std;
  5. const int N=2e5+5;
  6. int n,k;
  7. int under[N],res[N]; //under是向下传递数组,res是答案数组
  8. int si[N]; //表示牌顶编号为i的那堆牌的数量
  9. set<int> st;
  10. int main()
  11. {
  12. memset(under,-1,sizeof under);
  13. memset(res,-1,sizeof res); //初值都赋为-1
  14. cin>>n>>k;
  15. for(int i=1;i<=n;i++){
  16. int p;cin>>p;
  17. auto it=st.lower_bound(p); //用lower_bound找到要放的那一堆牌
  18. if(it==st.end()){
  19. st.insert(p);
  20. si[p]=1; //如果找不到,那么就新建一个牌堆
  21. }else{
  22. under[p]=*it; //找到了,就把牌放在这个牌堆上,并更新under数组
  23. si[p]=si[*it]+1;
  24. st.erase(it);
  25. st.insert(p); //将牌顶元素更新为p
  26. }
  27. if(si[p]==k){
  28. st.erase(p);
  29. int x=p;
  30. for(int j=0;j<k;j++){
  31. res[x]=i;
  32. x=under[x];
  33. }
  34. }//若牌数达到k,则向下标记元素,并移除这堆牌
  35. }
  36. for(int i=1;i<=n;i++) cout<<res[i]<<endl;
  37. return 0;
  38. }

完结撒花~~~

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注