7-11 彩虹瓶 (25分)
1.题意
彩虹瓶的制作过程:先把一大批空瓶铺放在装填场地上,然后按照一定的顺序将每种颜色的小球均匀撒到这批瓶子里。假设彩虹瓶里要按顺序装 N 种颜色的小球(不妨将顺序就编号为 1 到 N)。现在工厂里有每种颜色的小球各一箱,工人需要一箱一箱地将小球从工厂里搬到装填场地。如果搬来的这箱小球正好是可以装填的颜色,就直接拆箱装填;如果不是,就把箱子先码放在一个临时货架上,码放的方法就是一箱一箱堆上去。当一种颜色装填完以后,先看看货架顶端的一箱是不是下一个要装填的颜色,如果是就取下来装填,否则去工厂里再搬一箱过来。如果工厂里发货的顺序比较好,工人就可以顺利地完成装填。例如要按顺序装填 7 种颜色,工厂按照 7、6、1、3、2、5、4 这个顺序发货,则工人先拿到 7、6 两种不能装填的颜色,将其按照 7 在下、6 在上的顺序堆在货架上;拿到 1 时可以直接装填;拿到 3 时又得临时码放在 6 号颜色箱上;拿到 2 时可以直接装填;随后从货架顶取下 3 进行装填;然后拿到 5,临时码放到 6 上面;最后取了 4 号颜色直接装填;剩下的工作就是顺序从货架上取下 5、6、7 依次装填。但如果工厂按照 3、1、5、4、2、6、7 这个顺序发货,工人就必须要愤怒地折腾货架了,因为装填完 2 号颜色以后,不把货架上的多个箱子搬下来就拿不到 3 号箱,就不可能顺利完成任务。
另外,货架的容量有限,如果要堆积的货物超过容量,工人也没办法顺利完成任务。例如工厂按照 7、6、5、4、3、2、1 这个顺序发货,如果货架够高,能码放 6 只箱子,那还是可以顺利完工的;但如果货架只能码放 5 只箱子,工人就又要愤怒了……
输入首先在第一行给出 3 个正整数,分别是彩虹瓶的颜色数量 N、临时货架的容量 M、以及需要判断的发货顺序的数量 K。随后 K 行,每行给出 N 个数字,是 1 到N 的一个排列,对应工厂的发货顺序。对每个发货顺序,如果工人可以愉快完工,就在一行中输出 YES;否则输出 NO。
2.题解
用栈来模拟。
3.代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 int main(){ 4 int n, m, k; 5 int a; 6 scanf("%d %d %d\n", &n, &m, &k); 7 while(k--) { 8 stack<int> s; 9 int c = 1; 10 int f = 0; 11 for(int i = 0; i < n; i++) { 12 scanf("%d", &a); 13 if(a == c) { 14 c++; 15 while(s.size()) { 16 if(s.top() == c) { 17 s.pop(); 18 c++; 19 } 20 else { 21 break; 22 } 23 } 24 } else { 25 s.push(a); 26 if(s.size() > m) { 27 f = 1; 28 } 29 } 30 } 31 if(f || c < n) { 32 printf("NO\n"); 33 } else { 34 printf("YES\n"); 35 } 36 } 37 38 return 0; 39 }
1.题意
给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜面反转,再输出反转后的层序遍历的序列。所谓镜面反转,是指将所有非叶结点的左右孩子对换。这里假设键值都是互不相等的正整数。
2.题解
在前序遍历中找出根节点,根据根节点在中序遍历中的位置划分左子树与右子树,递归。镜像翻转只要在层序遍历时先向队列中放入右节点即可。
3.代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 int a[35],b[35]; 4 queue<int>q; 5 vector<int>v; 6 vector<int>::iterator it; 7 struct treenode { 8 int l, r; 9 }t[35]; 10 int findtree(int a1, int a2, int b1, int b2) { 11 int root, pos; 12 if(a2 - a1 == 0) { 13 return b1; 14 } 15 if(a2 - a1 < 0) { 16 return -1; 17 } 18 19 root = b1; 20 for(int i = a1; i <= a2; i++) { 21 if(b[root] == a[i]) { 22 pos = i; 23 break; 24 } 25 } 26 t[root].l = findtree(a1, pos - 1, b1 + 1, b1 + pos - a1); 27 t[root].r = findtree(pos + 1, a2, b1 + pos - a1 + 1, b2); 28 return root; 29 } 30 void printtree(int n) { 31 int temp; 32 q.push(n); 33 while(!q.empty()) { 34 temp = q.front(); 35 q.pop(); 36 v.push_back(b[temp]); 37 if(t[temp].r != -1) { 38 q.push(t[temp].r); 39 } 40 if(t[temp].l != -1) { 41 q.push(t[temp].l); 42 } 43 } 44 } 45 int main() { 46 int n; 47 scanf("%d", &n); 48 for(int i = 1; i <= n; i++) { 49 t[i].l = t[i].r = -1; 50 scanf("%d", &a[i]); 51 } 52 for(int i = 1; i <= n; i++) { 53 scanf("%d", &b[i]); 54 } 55 56 findtree(1, n, 1, n); 57 printtree(1); 58 cout << *v.begin(); 59 for(it = v.begin() + 1; it != v.end(); it++) { 60 cout<<' '<<*it; 61 } 62 63 return 0; 64 }