HDU 5596 GTW likes gt

来源:互联网 发布:v2ex python版 编辑:程序博客网 时间:2024/05/16 12:48

题意:

从前,有nn只萌萌的GT,他们分成了两组在一起玩游戏。他们会排列成一排,第ii只GT会随机得到一个能力值b_ibi。在第ii秒的时候,第ii只GT可以消灭掉所有排在他前面的和他不是同一组的且能力值小于他的GT。为了使游戏更加有趣,GT的首领GTW会发功mm次,第ii次发功的时间为c_ici,则在第c_ici秒结束后,b_1,b_2,...,b_{c_i}b1,b2,...,bci都会增加1。现在,GTW想知道在第nn秒之后,会有几只GT存活下来。

这个题就是凸显出了自己智商低的一个典范,我一直在想前面的怎么加,不能一直循环相加,后来终于想明白了可以先把前面的统一加起来,是不影响后面的,因为在当前那秒的时候,你只需要知道前面的数是多少就是了,你当前这个数加了多少,你前面的数就该加多少,所以不影响。我只需要倒着走就行了。

后来还是没有搞出来,看了官方题解,我就发现我是傻了,都快要做出来了。他有一个转换,其实不算和,就算减的,前面都加1,相当于后面都减一,我就可以顺着做了。郁闷


#include<cstdio>#include<cstdlib>#include<cstring>#include<queue>#include<vector>#include<set>#include<iostream>#include<algorithm>using namespace std;int n,m;int a[50005];int b[50005];int c[50005];int main(){    int t;    scanf("%d",&t);    while(t--)    {        priority_queue<int,vector<int>,greater<int> >q1;//相当于从小到大        priority_queue<int,vector<int>,greater<int> >q0;<span style="font-family: Arial, Helvetica, sans-serif;">//相当于从小到大</span>        scanf("%d%d",&n,&m);        for(int i=0;i<n;i++)            scanf("%d%d",&a[i],&b[i]);        memset(c,0,sizeof(c));        for(int i=1;i<=m;i++)        {            int x;            scanf("%d",&x);            c[--x]++;        }        int cnt=0;        int ans=0;        for(int i=0;i<n;i++)        {            b[i]-=cnt;减去之前的发功次数            printf("%d %d\n",b[i],cnt);            cnt+=c[i];//累加当前是否发功,发功几次            if(a[i]==0)//检查当前他可以打死不是和他一个队伍,并且比他小的            {                while(!q1.empty()&&q1.top()<b[i])                {                    //printf("%d\n",q1.top());                    ans++;//记下个数                    q1.pop();                }                q0.push(b[i]);            }            else            {                while(!q0.empty()&&q0.top()<b[i])                {                    //printf("%d\n",q0.top());                    ans++;                    q0.pop();                }                q1.push(b[i]);            }        }        printf("%d\n",n-ans);    }}



0 0
原创粉丝点击