HDU
来源:互联网 发布:java实现链表反转 编辑:程序博客网 时间:2024/06/14 15:31
传送门:HDU5493
题意:给出n个人的身高和每个人前面或者后面有多少人比他高(不知道是前面还是后面),问能否构造出一个合法的序列。
思路1:将所有人按身高从小到大排序,然后一个个取出来插入线段树,插入线段树的时候要保证前面留出足够的空来给比他高的人,又因为要字典序最小,那么我们插入的位置就是要min(ki, n - i - ki - 1) + 1.
代码:
#include<bits/stdc++.h>#define ll long long#define lson l, mid, rt << 1#define rson mid + 1, r, rt << 1 | 1using namespace std;const int MAXN = 100010;struct node{ int h, k; bool operator < (node a) const{ return h < a.h; }}p[MAXN];int tree[MAXN << 2], ans[MAXN];void build(int l, int r, int rt){ if(l == r){ tree[rt] = 1; return ; } int mid = (l + r) >> 1; build(lson); build(rson); tree[rt] = tree[rt << 1] + tree[rt << 1 | 1];}void update(int x, int val, int l, int r, int rt){ if(l == r) { ans[l] = val; tree[rt] = 0; return ; } int mid = (l + r) >> 1; if(x >= tree[rt << 1]) update(x - tree[rt << 1], val, rson); else update(x, val, lson); tree[rt] = tree[rt << 1] + tree[rt << 1 | 1];}int main(){ int T, n, kase = 1; cin >> T; while(T--) { scanf("%d", &n); build(1, n, 1); for(int i = 0; i < n; i++) scanf("%d %d", &p[i].h, &p[i].k); sort(p, p + n); bool ok = 1; for(int i = 0; i < n; i++) { if(n - i - p[i].k <= 0){ ok = 0; break; } update(min(p[i].k, n - i - p[i].k - 1), p[i].h, 1, n, 1);//前面留min()个空位置 } printf("Case #%d: ", kase++); if(!ok){ cout << "impossible\n"; continue; } for(int i = 1; i <= n; i++) printf("%d%c", ans[i], " \n"[i == n]); }}思路2:将所有人身高按从大到小排序,每次取出一个人来插入Treap中,Treap维护已经构造出来的序列,那么新加的人插入的位置就是min(ki, x - ki) + 1。
Treap学习及模板:点击打开链接
代码:
#include<bits/stdc++.h>using namespace std;const int MAXN = 100010;struct Treap{ int size; int key,fix; Treap *ch[2]; Treap(int key) { size=1; fix=rand(); this->key=key; ch[0]=ch[1]=NULL; } int compare(int x) const { if(x==key) return -1; return x<key? 0:1; } void Maintain() { size=1; if(ch[0]!=NULL) size+=ch[0]->size; if(ch[1]!=NULL) size+=ch[1]->size; }};void Rotate(Treap* &t,int d){ Treap *k=t->ch[d^1]; t->ch[d^1]=k->ch[d]; k->ch[d]=t; t->Maintain(); k->Maintain(); t=k;}void Insert(Treap* &t,int pos, int val){ if(t==NULL) t=new Treap(val); else { int d; if(pos <= (t->ch[0] ? t->ch[0]->size : 0)) d = 0; else { d = 1; pos = pos - (t->ch[0] ? t->ch[0]->size : 0) - 1;//注意这里,每个子树的下标都是从零开始的,因此进入右子树时下标要-1 } Insert(t->ch[d], pos, val); if(t->ch[d]->fix > t->fix) Rotate(t, d^1); } t->Maintain();}void Print(Treap *t){ if(t==NULL) return; Print(t->ch[0]); printf(" %d", t->key); Print(t->ch[1]); delete t;//本题要注意在这里释放空间 }struct node{int h, k;bool operator < (node a) const{return h > a.h;}}p[MAXN];int main(){ int T, n, kase = 1; cin >> T; while(T--) { scanf("%d", &n); for(int i = 0; i < n; i++) scanf("%d %d", &p[i].h, &p[i].k); sort(p, p + n); Treap *root = NULL; bool ok = 1; for(int i = 0; i < n; i++) { int pos = min(p[i].k, i - p[i].k);if(pos < 0){ok = 0; break;}Insert(root, pos, p[i].h); } printf("Case #%d:", kase++); if(!ok)puts(" impossible"); else Print(root), puts(""); } return 0;}
Treap效率稍微比线段树差一点,可能是要申请和释放空间的缘故。
阅读全文
0 0
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- HDU
- 浅谈DNS域名解析过程
- UART串口通信
- 在Eric创建工程时,提示找不到QT designer
- java基础到框架,笔记视频全部都有。
- THREE.js鼠标选取拖拉的原理与实现
- HDU
- Linux 审计工具 auditd 命令
- HTML表格多行表头,隔行变色,点击变色的实现
- nagios3.5.1 server端源码编译安装方式
- python处理字符串(2)
- HTTP
- Javascript学习笔记(二)
- unity android真机调试
- 华为 防火墙 ipsec-VPN