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;}
- Poj 2828 Buy Tickets \ Zoj 3635 Cinema in Akiba
- ZOJ-3635-Cinema in Akiba
- ZOJ 3635 Cinema in Akiba
- zoj 3635 Cinema in Akiba
- ZOJ 3635 Cinema in Akiba[ 块状数组 ]
- ZOJ 3635 Cinema in Akiba【线段树】
- ZOJ 3635 Cinema in Akiba(树状数组 + 二分)
- ZOJ 3635 Cinema in Akiba (树状数组+二分)
- zoj 3635 Cinema in Akiba(树状数组+二分)
- ZOJ 3635 Cinema in Akiba(线段树)
- ZOJ 题目3635 Cinema in Akiba(线段树插空)
- ZOJ 3635 Cinema in Akiba(二分+树状数组)
- zoj 3635 Cinema in Akiba 二分+树状数组
- ZOJ3635 Cinema in Akiba
- zoj3635 Cinema in Akiba
- ZOJ 3635——Cinema in Akiba(树状数组+二分)
- zoj 3635 Cinema in Akiba 树状数组求第K大
- poj 2828 Buy Tickets
- eclipse下无法连接到github的解决办法
- 文笔又不好,学艺又不精,管他呢,随便开始吧。
- PowerShell 将对象转换成文本
- php C++ 扩展
- CUDA5.0+VS2008+VisualAssist安装以及配置
- Poj 2828 Buy Tickets \ Zoj 3635 Cinema in Akiba
- Session设置失效(转帖备忘)
- JMeter使用指南 提高编
- SMS-MMS加载列表显示
- 关于Maven找不到jar包的解决方案
- javascript去除空格
- jsp中servlet的几种跳转方式
- MYSQL 字段时间戳转换为可读日期时间
- android学习-对话框的动画弹出和动画消失