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 }
View Code

 

7-12 玩转二叉树 (25分)

 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 }
View Code

 

 
 
posted on 2020-11-15 22:13  吕瓜皮  阅读(105)  评论(0编辑  收藏  举报