Poj 2828 Buy Tickets \ Zoj 3635 Cinema in Akiba

来源:互联网 发布:拉菲尔定律工资计算法 编辑:程序博客网 时间:2024/06/05 16:24

这两道题思路是一样的。

第一题:http://poj.org/problem?id=2828

题意:依次插入人,每个人插入的地方告知,求最终的排位。

乍看用链表来做即可,可是这样肯定会超时,不信试试:

#include <iostream>#include <stdlib.h>#include <stdio.h>using namespace std;struct People{    int val;    People() {}    People(int _val)    {        val = _val;        next = NULL;    }    People * next;};int size = 0;int main(){#ifndef ONLINE_JUDGE    freopen("in.txt","r",stdin);#endif    int n;    int pos,val;    int size = -1;    while(scanf(" %d",&n)!=EOF)    {        People * head;        People * last;        head = last = new People(-1);        size = 0;        for(int i=0; i<n; i++)        {            scanf(" %d %d",&pos,&val);            if(size <= pos)            {                last->next = new People(val);                last = last->next;            }            else            {                People * temp = head;                int count = 0;                while(temp!=NULL)                {                    if(count == pos)                    {                        break;                    }                    temp = temp->next;                    count++;                }                People * cur = temp->next;                temp->next = new People(val);                temp->next->next = cur;            }            size++;        }        People *temp = head->next;        if(temp!=NULL)        {            while(temp->next!=NULL)            {                printf("%d ",temp->val);                temp = temp->next;            }            printf("%d",temp->val);        }        printf("\n");    }    return 0;}

其实我们可以这样想,题目中的数据是一次插入的。如果我们反过来思考,从后往前的话,最后一个人的位置肯定不发生变化,接下来,在最后一个人位置不发生变化的情况下,倒数第二个人的位置也不发生变化,一次类推。我们只要用线段树维护一个关于区间空位个数的数组即可。

#include <iostream>#include <stdlib.h>#include <stdio.h>using namespace std;#define Maxn 200005#define lx (x<<1)#define rx ((x<<1)|1)#define MID ((l + r)>>1)struct People{    int pos;    int val;};People p[Maxn];//维护空位int S[Maxn<<2];//最后的序列int A[Maxn];void pushUp(int x){    S[x] = S[lx] + S[rx];}void build(int l,int r,int x){    if(l == r)    {        S[x] = 1;        return;    }    build(l,MID,lx);    build(MID+1,r,rx);    pushUp(x);}void update(int p,int d,int l,int r,int x){    if(l == r)    {        S[x] = 0;        A[l] = d;        return;    }    if(p<S[lx]) update(p,d,l,MID,lx);    else update(p-S[lx],d,MID+1,r,rx);    pushUp(x);}int main(){    #ifndef ONLINE_JUDGE    freopen("in.txt","r",stdin);    #endif    int n;    while(scanf(" %d",&n)!=EOF)    {        for(int i=0;i<n;i++)        {            scanf(" %d %d",&p[i].pos,&p[i].val);        }        build(0,n-1,1);        for(int i=n-1;i>=0;i--)        {            update(p[i].pos,p[i].val,0,n-1,1);        }        for(int i=0;i<n-1;i++)        {            printf("%d ",A[i]);        }        printf("%d\n",A[n-1]);    }    return 0;}

第二题:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3635

这题是类似的,也是维护空位个数。

#include <iostream>#include <stdlib.h>#include <stdio.h>using namespace std;#define Maxn 50005#define lx (x<<1)#define rx ((x<<1)|1)#define MID ((l + r)>>1)int S[Maxn<<2];int A[Maxn];//排位int rank[Maxn];void pushUp(int x){    S[x] = S[lx] + S[rx];}void build(int l,int r,int x){    if(l == r)    {        S[x] = 1;        return;    }    build(l,MID,lx);    build(MID+1,r,rx);    pushUp(x);}void update(int p,int d,int l,int r,int x){    if(l == r)    {        S[x] = 0;        A[l] = d;        rank[d] = l;        return;    }    if(p<S[lx]) update(p,d,l,MID,lx);    else update(p-S[lx],d,MID+1,r,rx);    pushUp(x);}int main(){    #ifndef ONLINE_JUDGE    freopen("in.txt","r",stdin);    #endif    int n;    int p;    int q;    while(scanf(" %d",&n)!=EOF)    {        build(1,n,1);        for(int i=1;i<=n;i++)        {            scanf(" %d",&p);            p--;            update(p,i,1,n,1);        }        scanf(" %d",&q);        for(int i=1;i<=q;i++)        {            scanf(" %d",&p);            printf("%d",rank[p]);            if(i!=q) printf(" ");        }        puts("");    }    return 0;}


原创粉丝点击