数据结构 hbb(汉堡包)
数据结构 hbb(汉堡包)
问题描述
汉堡包有收集汉犇犇的癖好,它喜欢把汉犇犇一个叠一个的放置。
因为它有强迫症,所以每当它想放一个新的汉犇犇进去的时候并不一定想直
接叠在最上面,简单的说,当他想放第 A 个新的汉犇犇的时候,他想把它插入到
汉犇犇 Ai(保证汉犇犇 Ai 存在)的上面;
除此之外,有时候他会吃掉收集的部分汉堡包,因为不满足于只吃一个,每
次会吃掉某个汉犇犇开始,往上连续的 x(x>=1)个汉犇犇。
给定 n 个操作,输出 n 个操作后活下来的汉犇犇的编号(从最底下的汉犇犇
开始到最顶):
1 a : 1 代表一个新的汉犇犇(第一个出现的汉犇犇编号为 1,第二个为 2,以此类推),汉堡包想把他放在编号为 a 的汉犇犇上面,如果不存在编号 a的汉犇犇,则放在所有汉犇犇的最上面即可;
2 a b : 2 代表汉堡包想吃掉编号 a 的汉犇犇开始(如果 a 不存在则从最底下的汉堡包开始),按叠好的顺序,往上共计 b 个汉犇犇(算上编起始位置一共 b 个),若不够 b 个,则吃到顶结束;
★数据输入 |
输入第一行为一个正整数 n,代表操作数量。 |
接下来 n 行操作,如题意; |
对于 50%的数据, 1<=n<=1000; |
对于 100%的数据, 1<=n<=100000, 0 <= a, b <= 100000 |
★数据输出 |
输出自底向上的汉犇犇编号,数字之间用空格隔开,行末无空格,无换行; |
输入示例 | 输出示例 |
3 1 10 1 10 1 1 |
1 3 2 |
输入示例 | 输出示例 |
4 1 10 1 10 1 1 2 1 2 |
2 |
示例一解释:
(1) 第一个操作,加入汉犇犇 1 放在汉堡包 10 上面,汉堡包 10 不存在,所以直
接放最上{ 1 }
(2) 第二个操作,加入汉犇犇 2 放在汉犇犇 10 上面,汉犇犇 10 不存在,所以
直接放最上{ 1, 2}
(3) 第三个操作,加入汉犇犇 3 放在汉犇犇 1 上面,汉犇犇 1 存在,所以放 1
上{ 1, 3, 2}
示例二解释:
(1) 前面部分操作和示例一一样,为 {1, 3, 2};
(2) 接着汉堡包吃掉汉犇犇 1 是的 2 个汉犇犇,所以{1, 3}被吃掉
(3) 故输出 2
解题思路
双向链表+数组存对应节点的地址
code(未验证)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <iostream> 4 using namespace std; 5 #include <string.h> 6 7 #define MAXN 100002 8 9 struct Node 10 { 11 Node(int _data) 12 :data(_data),bef(NULL),next(NULL){} 13 int data; 14 Node *bef;//before 15 Node *next; 16 }; 17 18 Node *addr[MAXN] = {0}; 19 Node *head = NULL, *tail = NULL; 20 21 void Init(); 22 void Insert(int &prenum,int &thisnum); 23 void Eat(int &start,int &num); 24 void DisAll(); 25 26 int main() 27 { 28 Init(); 29 DisAll(); 30 31 return 0; 32 } 33 34 void Init() 35 { 36 int i=0,j=0; 37 int opnum=0,op=0,hbbnum=1; 38 int a=0,b=0; 39 40 scanf("%d",&opnum); 41 head = new Node(-1); 42 tail = head; 43 44 for(i=1;i<=opnum;i++) 45 { 46 scanf("%d",&op); 47 if(op==1) 48 { 49 scanf("%d",&a); 50 Insert(a,hbbnum); 51 ++hbbnum; 52 } 53 else//op==2 54 { 55 scanf("%d %d",&a,&b); 56 Eat(a,b); 57 } 58 // DisAll(); 59 } 60 } 61 62 void Insert(int &prenum,int &thisnum) 63 { 64 Node *pnew = new Node(thisnum); 65 if(addr[prenum] && addr[prenum]->next)//要找的数存在 且 不是最后一个 66 { 67 addr[thisnum] = pnew; 68 pnew->next = addr[prenum]->next; 69 addr[prenum]->next->bef = pnew; 70 pnew->bef = addr[prenum]; 71 addr[prenum]->next = pnew; 72 } 73 else//数不存在 或 数是最后一个 74 { 75 addr[thisnum] = pnew; 76 pnew->bef = tail; 77 tail->next = pnew; 78 tail = pnew; 79 } 80 } 81 82 void Eat(int &start,int &num) 83 { 84 int i; 85 Node *p; 86 if(addr[start]==NULL)//要找的数不存在,从头开始删 87 { 88 for(i=1, p=head->next; p && i<=num; i++, p=p->next) 89 { 90 addr[p->data] = NULL; 91 } 92 head->next = p; 93 if(p==NULL) tail = head; 94 else p->bef = head; 95 } 96 else//找的数存在,获取地址,开始删 97 { 98 Node *pl = addr[start]->bef; 99 for(i=1, p=addr[start]; p && i<=num; i++, p=p->next) 100 { 101 addr[p->data] = NULL; 102 } 103 pl->next = p; 104 if(p==NULL) tail = pl; 105 else p->bef = pl; 106 } 107 } 108 109 void DisAll() 110 { 111 for(Node *p = head->next; p; p=p->next) 112 { 113 if(p==head->next) 114 printf("%d",p->data); 115 else 116 printf(" %d",p->data); 117 } 118 }