8月7日假期集训T3

 

 

 

题意学长给的挺详细的了,就不解释了......

在学长的课件里面给出了很多的做法,这里就只说一下学长最后说的可以过的方法吧。

对于数列中的每一个‘1’,我们都可以用一个长度为T的数组来记录每一个的行动状态,即用‘1’来表示向左移动一位,用‘0’来表示静止不动(就是其前面有'1'挡路啦),例如数列0001,T=3时里面那个1的运动状态就可以表示为111(即向左移动3位),现在我们考虑先把样例里面每一个的1的运动状态都弄一下,

原数组:1 0 0 1 0 1 1 1 0 1    T=3

运动状态(表示从左到右的每一个‘1’):000 ; 110 ; 111 ; 011 ; 001 ; 101。

 发现了什么没有,是不是我们先假设最初数组为000,之后我们每遇到一个‘1’,都在原数组的基础上先右移一位,再在前面插入一个‘0’,每遇到一个‘0’,都是把数组里面的第一个‘0’变为了1。其实对于这两条我们可以这样理解,对于我们扫到的一个‘1’,可能都会阻挡之后的‘1’前进的步伐,每遇到一个‘0’,就相当于后面的‘1’都可以比前面的‘1’多前进一步。相隔数个‘0’的两个‘1’,它们在前面的‘1’没有阻拦的情况下前进的步伐一样,如果有前面有阻拦且后面的还可以走,它的最终位置就是在前面的点的后面,就是砍去了前面的运动状态的最后一步(前面的'1'导致的右移一位),并且对于前面走不动的情况下,后面的点还可以进行移动,就是我们的将‘1’变为‘0’的情况。相隔数个‘1’的两个‘1’,他们前进的区别就是后面的‘1’要在前面的阻挡都清空的情况下才可以走前面的'1'的路,即我们的右移并补‘0’的操作。

这样我们剩下的问题就是维护那个队列了,我这里为方便下标修改每一个‘0’,用的是手模的deque,并且又用了一个deque来记录数列里面每个‘0’的位置,由于我们插入‘0’的操作只有向前插入‘0’,那么插入的‘0’的下标就是单调递减的,我们每次放‘0’就把‘0’的下标放入队首,队列里面的坐标就是单增的,我们每次修改从队首取出第一个‘0’的位置,用下标直接修改就可以啦~

对于答案的统计,计算的同时求一下‘1’的个数,初坐标减去该个数就是最后的位置,记录一下就行了。

(貌似好像STL的deque也可以下标修改,但juruo太菜了不会用QAQ)

代码:

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=3e6+10;
 4 int q[5000000],head,back; //512mb,数组随便开吧~
 5 deque<int>qq; //存‘0’的下标用
 6 int a[N],ans[N],tot;  //tot记录此时数列的‘1’的个数,最后该‘1’右移了tot位,用于统计答案
 7 int main(){
 8     int n,k;
 9     scanf("%d%d",&n,&k);
10     head=3500000; back=head-1;
11     for(int i=1;i<=k;++i){
12         qq.push_back(back+1); //先存一下初始状态
13         q[++back]=0;
14     }
15     for(int i=1;i<=n;++i){
16         scanf("%d",&a[i]);
17         if(a[i]){
18             ans[i-tot]=1;  //记录答案
19             if(q[back]) tot--;  //进行pop队尾
20             else{
21                 if(!qq.empty())
22                     qq.pop_back();
23             }
24             back--;
25             q[--head]=0;
26             qq.push_front(head); //push新的‘0’的下标
27         }
28         else{
29             if(!qq.empty()){
30                 q[qq.front()]=1;
31                 qq.pop_front();
32                 tot++;
33             }
34         }
35     }
36     for(int i=1;i<=n;++i)  //输出答案
37         printf("%d ",ans[i]);
38     puts("");
39     return 0;
40 }
View Code

 

posted @ 2020-08-07 17:38  19502-李嘉豪  阅读(172)  评论(3)    收藏  举报