2019-07-08考试记录

T1 字符串编辑

问题描述: 
    为了对一些资料进行保密,奶牛们要对某些文章进行编辑。编辑的方法很奇特:要把原有文章 
的某些词句按照某些规则用另一些词句代替。规则的形式如下:原串 新串,表示把原串替换成 
新串。假设有n 条规则,第 i 规则的原串和新串分别为Mi 和Ni,则编辑按如下过程进行:开始 
编辑时,先使用第一条规则,把文章中出现的第一个M1 替换成N1,如果替换后的新文章还存在 
M1,则如上处理,直到文章不存在M1 为止;然后用同样的方法使用第2,第3,……,第n 条 
规则进行替换,直到所有的规则都用完为止。 
    注意: 
       1、每次都要从文章开头开始找要替换的词句 
       2、一条规则一旦使用完后,将不能再使用 
       3、每一篇文章都是可编辑的 
       如有四条规则: 
       1. ban→bab 
       2. baba→be 
       3. ana→any 
       4. ba b→hind the g 
       要编辑的文章为“banana boat”,则编辑的过程如下: 
       编辑顺序           编辑前的文章            编辑后的文章            使用的规则 
       1          banana boat           babana boat       1 
       2          babana boat           bababa boat       1 
       3          bababa boat           beba boat         2 
       4          beba boat             behind the goat   4 
       编辑后的文章为“behind the goat”。请编写一程序,帮助组委会对给定的文章进行编辑。 

输入格式: 
    数据存放在当前目录下的文本文件“editing.in”中。 
    文件共有 2n+2 行。文件的第一行是一个整数n (1<=n<=10),表示规则的数目;接下来第2i 
行及第2i+1 行分别表示Mi 和Ni(1<=i<=n),其长度均不超过80 个字符,且Mi 不为空串;最 
后一行是要编辑的文章,长度不超过80 个字符。行末没有空格。 

输出格式: 
    答案输出到当前目录下的文本文件“editing.out”中。 
    文件只有一行,表示编辑后的文章(长度不超过80 个字符)。行末也应该没有空格。 

样例1 输入:                          样例1 输出: 
4                                behind the goat 
ban bab 
baba be 
ana any 
ba b 
hind the g 
banana boat 

样例2 输入:                          样例2 输出: 
1                                shoe or shop 
t 
sh 
toe or top 
题面

思路:有点恶心的模拟,核心部分在于字符串替换是主串后部分的挪动

考试得分:40 pts

改后得分:80 pts

改后代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 int n, strl;
 5 char Mi[20][1000], Ni[20][1000], para[1000];
 6 
 7 int init() {
 8     int pos;
 9     char c;
10     scanf("%d\n", &n);
11     for(int i = 1; i <= n; i++) {
12         gets(Mi[i]+1);
13         gets(Ni[i]+1);
14     }
15     gets(para+1);
16     strl = strlen(para+1);
17     return 0;
18 }
19 
20 void change(int curr, int posc) {
21     int strla = strlen(Mi[curr]+1), strlb = strlen(Ni[curr]+1);
22     if(strla > strlb) {
23         for(int i = posc+strlb; i <= strl; i++) {
24             para[i] = para[i+strla-strlb];
25         }
26     }
27     if(strla < strlb) {
28         for(int i = strl; i >= posc+strla-1; i--) {
29             para[i+strlb-strla] = para[i];
30         }
31     }
32     for(int i = posc; i <= posc+strlb-1; i++) {
33         para[i] = Ni[curr][i-posc+1];
34     }
35     strl = strlen(para+1);
36     return ;
37 }
38 
39 int solve() {
40     int tag = 0;
41     for(int i = 1; i <= n; i++) {
42         int strlu = strlen(Mi[i]+1);
43         for(int j = 1; j <= strl; j++) {
44             for(int k = 1; k <= strlu; k++) {
45                 if(Mi[i][k] != para[j+k-1]) {
46                     tag = 1;
47                     break;
48                 }
49             }
50             if(tag == 0) {
51                 change(i, j);
52             }
53             tag = 0;
54         }
55     }
56     for(int i = 1; i <= strl; i++) {
57         printf("%c", para[i]);
58     }
59     return 0;
60 }
61 
62 int main() {
63     freopen("editing.in", "r", stdin);
64     freopen("editing.out", "w", stdout);
65     init();
66     solve();
67     return 0;
68 }
Editing

Tips:题目的描述没有非常清晰,根据$data1$与$data2$的答案来看,在规则$2$完全使用之后如果主串还出现了规则$1$可以进行编辑的内容,则应该继续使用规则$1$进行编辑,但是题目并没有说清楚


 T2 产品加工

问题描述: 
    众所周知,一个产品的生产可能要经历好几道工序,OHOW 工厂生产的产品也是如此。工厂首 
先将原料加工,得到最初产品A,接着将产品A 加工成次成品B,最后次成品B 加工成成品C。各级 
产品的生产由不同的生产流水线完成。可是工厂的经理SZ 先生遇到了点麻烦,由于每种产品可能 
有多条流水线生产,使得生产出来的产品相当凌乱,SZ 先生为了提高生产的效率,决定调换一些 
产品的位置(每次只能两两调换),将相同产品放在一起,并且所有的产品都摆成一条直线。比如 
最初的产品序列为:ABACB,那么SZ 先生希望得到的序列为AABBC。 
    注意:由于产品的特殊性,SZ 先生决定让产品最终的摆放顺序为A、B、C 
    由于工厂生产出的产品可能很多,为了节省人力、物力和时间,SZ 先生希望移动产品的次数 
最少,为此,他找到了他的朋友xx,希望xx 能借助计算机帮他解决这一难题。TZ 由于正在看越策 
越开心,他想请聪明的你来帮他解决这个问题,你能做到吗? 
输入数据 
    第一行是序列的长度N (1<=N<=1000000),随后一行为N 个产品的编号(产品由A、B、C 表示), 
第二行无空格。 
输出数据 
    输出数据仅一行,为调换产品的最少次数。 
样例输入 

9 
BBACCCBCA 
样例输出 
4 
题面

思路:本题其实是一道数学题,我们知道整个序列在排序之后可以分为A,B,C共3区域

所以我们统计错位的字母数量(如A字母在B区域的数量,B字母在A区域的数量……)

我们记A字母在B区域为AB,于是有AB,BA,AC,CA,BC,CB六种情况

显然,AB与BA,AC与CA,BC与CB是可以抵消的,每抵消一对$ans+1$

抵消之后必然是A,B,C三者的错位情况,每抵消一对(三个)$ans+2$

这个思路的正确性在于,将每个字母移到对应的正确区域内一定是最优的

考试得分:0 pts

改后得分:100 pts

改后代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 int n, na, nb, nc, ab, ba, ca, ac, bc, cb, ans, use;
 5 char prod[1000005];
 6 
 7 int init() {
 8     scanf("%d\n", &n);
 9     for(int i = 1; i <= n; i++) {
10         scanf("%c", &prod[i]);
11         if(prod[i] == 'A') na++;
12         else if(prod[i] == 'B') nb++;
13         else nc++;
14     }
15     return 0;
16 }
17 
18 int solve() {
19     for(int i = 1; i <= na; i++) {
20         if(prod[i] == 'B') ab++;
21         else if(prod[i] == 'C') ac++;
22     }
23     for(int i = na+1; i <= na+nb; i++) {
24         if(prod[i] == 'A') ba++;
25         else if(prod[i] == 'C') bc++;
26     }
27     for(int i = na+nb+1; i <= n; i++) {
28         if(prod[i] == 'A') ca++;
29         else if(prod[i] == 'B') cb++;
30     }
31 //    printf("na:%d nb:%d nc:%d ab:%d ba:%d ac:%d ca:%d bc:%d cb:%d\n", na, nb, nc, ab, ba, ac, ca, bc, cb);    
32     use = min(ab, ba), ans += use, ab -= use, ba -= use;
33     use = min(ac, ca), ans += use, ac -= use, ca -= use;
34     use = min(bc, cb), ans += use, bc -= use, cb -= use;
35 //    printf("na:%d nb:%d nc:%d ab:%d ba:%d ac:%d ca:%d bc:%d cb:%d\n", na, nb, nc, ab, ba, ac, ca, bc, cb);
36     ans += ab * 2;
37     ans += ba * 2;
38     printf("%d", ans);
39     return 0;
40 }
41 
42 int main() {
43     freopen("process.in", "r", stdin);
44     freopen("process.out", "w", stdout);
45     init();
46     solve();
47     return 0;
48 }
Process

Tips:由于数据问题测试分数只有40 pts,但是实际上这个代码是能够拿满分的


 T3 迷宫

问题描述: 
    小希非常喜欢玩迷宫游戏,现在她自己设计了一个迷宫游戏。在她设计的迷宫中,首先她认为 
所有的通道都应该是双向连通的,就是说如果有一个通道连通了房间A 和B,那么既可以通过它从 
房间A 走到房间B,也可以通过它从房间B 走到房间A,为了提高难度,小希希望任意两个房间有 
且仅有一条路径可以相通(除非走了回头路)。小希现在把她的设计图给你,让你帮忙判断她的设 
计图是否符合她的设计思路。比如下面的例子,前两个是符合条件的,但是最后一个却有两种方法 
从5 到达8。 
数据输入: 
    输入包含多组数据,每组数据是一个以0 0 结尾的整数对列表,表示了一条通道连接的两个房 
 间的编号。房间的编号至少为1,且不超过100000。每两组数据之间有一个空行。 
 整个文件以两个-1 结尾。 
数据输出: 
    对于输入的每一组数据,输出仅包括一行。如果该迷宫符合小希的思路,那么输出"1",否则 
 输出"0"。 
输入输出样例: 
Migong.in 
 6 8  5 3  5 2  6 4 
 5 6  0 0 

 8 1  7 3  6 2  8 9  7 5 
 7 4  7 8  7 6  0 0 

 3 8  6 8  6 4 
 5 3  5 6  5 2  0 0 

 -1 -1 

Migong.out 
 1 
 1 
 0 
题面

思路:并查集+判断

考试得分:60 pts

改后得分:80 pts

改后代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 int fa[100005], rmb[100005];
 5 
 6 void start(int x) {
 7     for(int i = 1; i <= x; i++) fa[i] = i;
 8 }
 9 
10 int find(int x) {
11     if(x != fa[x]) fa[x] = find(fa[x]);
12     return fa[x];
13 }
14 
15 void amal(int x, int y) {
16     x = find(x);
17     y = find(y);
18     fa[y] = x;
19 }
20 
21 bool judge(int x, int y) {
22     x = find(x);
23     y = find(y);
24     return x == y;
25 }
26 
27 int solve() {
28     int a, b, tag = 0, same;
29     scanf("%d%d", &a, &b);
30     while(a != -1 && b != -1) {
31         start(100001);
32         memset(rmb, 0, sizeof(rmb));
33         while(a != 0 && b != 0 && a!= -1 && b != -1) {
34             rmb[a] = 1;
35             rmb[b] = 1;
36             if(judge(a, b) == true) {
37                 tag = 1;
38             }
39             amal(a, b);
40             scanf("%d%d", &a, &b);
41         }/*
42         for(int i = 1; i <= 100001; i++) {
43             if(rmb[i] == 1) {
44                 same = find(i);
45                 break;
46             }
47         }
48         for(int i = 1; i <= 100001; i++) {
49             if(rmb[i] == 1 && find(i) != same) {
50                 tag = 0;
51                 break;
52             }
53         }*/
54         if(tag == 1) {
55             tag = 0;
56             printf("0\n");
57             scanf("%d%d", &a, &b);
58             continue;
59         }
60         tag = 0;
61         printf("1\n");
62         scanf("%d%d", &a, &b);
63     }
64     return 0;
65 }
66 
67 int main() {
68     freopen("migong.in", "r", stdin);
69     freopen("migong.out", "w", stdout);
70     solve();
71     return 0;
72 }
Migong

Tips:到现在还没有搞明白怎么加上最后这个判断


T4 牛棚安排

【问题描述】 
    Farmer John的N(1<=N<=1000)头奶牛分别居住在农场所拥有的B(1<=B<=20)个牛棚的某一个 
 里。有些奶牛很喜欢她们当前住的牛棚,而另一些则讨厌再在它们现在所在的牛棚呆下去。 
FJ在忍受了若干次奶牛的抱怨后,决定为所有奶牛重新安排牛棚,使最不满的那头奶牛与最高 
兴的奶牛的心情差异最小,即使这会让所有奶牛都更加郁闷。 
    每头奶牛都把她对各个牛棚的好感度从高到低排序后告诉了FJ 。当然,如果一头奶牛被安排到 
的牛棚在她给出的列表中越靠后,她就会越郁闷。你可以认为奶牛的郁闷指数是她被分配到的牛棚 
在列表中的位置。奶牛们是斤斤计较的,她们无法容忍别的奶牛在自己喜欢的牛棚里快乐地生活, 
而自己却呆在一个自己不喜欢的牛棚里。每个牛棚都只能容纳一定数量的奶牛。FJ希望在每个牛棚 
都没有超出容量限制的前提下,使最郁闷和最高兴的奶牛的郁闷指数的跨度最小。 
    FJ请你帮他写个程序,来计算这个最小的郁闷指数跨度到底是多少。 
 【输入】 
    第1行:  包含2个用空格隔开的整数N和B,分别表示牛和牛棚的数量 
    第2..N+1行:  每行包含B个用空格隔开的整数,刚好完全包含1..B的整数。第i+1行的第一个整 
数,表示奶牛i最喜欢的牛棚编号。第二个整数表示奶牛i的列表中排在第二位,也就是她第二喜欢 
的牛棚。依此类推。 
    第N+2行:  包含B个用空格隔开的整数,第i个整数表示牛棚i最多能容纳的奶牛的数目。所有牛 
棚能容纳奶牛头数的和至少是N 。 
 【输出】 
    第1行:  输出一个整数,表示所有奶牛中最高兴与最郁闷的牛的郁闷指数跨度 
 【输入输出样例】 
stead.in                                stead.out 

6 4                                     2 
1 2 3 4 
2 3 1 4 
4 2 3 1 
3 1 2 4 
1 3 4 2 
1 4 2 3 
2 1 3 2 

 【样例说明】 
    每头奶牛都能被安排进她的第一或第二喜欢的牛棚。下面给出一种合理的分配方案:奶牛1和 
奶牛5住入牛棚1,牛棚2 由奶牛2独占,奶牛4住进牛棚3,剩下的奶牛3和奶牛6安排到牛棚4。
题面

思路:听老师说是二分图匹配,但是我不会做,考场上写了个爆搜,想加记忆化发现没法加

考场得分:10 pts

改后得分:NaN

改后代码:NULL


猜你喜欢

转载自www.cnblogs.com/CsyzFraction/p/11260682.html