PAT(乙级)2021年冬季考试
编程题得分:100总分:100
7-1 自动打包机 (15分)
一条哈密瓜自动打包流水线的工作程序是这样的:首先系统设定每箱哈密瓜应该有的总重量 W;然后传送带将一只只哈密瓜输送到一个自动称重设备上,根据称重结果进行以下操作:
- 如果称上的总重量正好达到 W,则将称上的所有哈密瓜装箱送走;
- 如果称上的总重量还不到 W,则将这只哈密瓜留在称上;
- 如果称上的总重量超过了 W,则将这只哈密瓜放到一边暂不处理。
本题就请你写个程序统计一下,究竟有多少只哈密瓜被装了多少箱?
输入格式:
输入第一行给出两个正整数 N(≤1000)和 W(≤104),分别为传送带上哈密瓜的数量和每箱的规定重量(克)。随后一行给出 N 个正整数,是传送带上每只哈密瓜的重量,单果重量不超过 2000 克。假设传送带按照输入的顺序传送哈密瓜到称重设备。
输出格式:
在一行中输出成功装箱的箱子数量和被装箱的哈密瓜的数量。数字间以 1 个空格分隔,行首尾不得有多余空格。
输入样例:
12 5000 2000 1500 1800 1000 1800 500 1900 1500 2000 1600 2000 2000
输出样例:
2 7
样例说明:
第 1、2、4、6 只瓜正好一箱;第 7、8、10 只瓜正好一箱。
评测结果
答案正确(15 分)
测试点得分
测试点 结果 得分 耗时 内存 0 答案正确 8 3.00 ms 312 KB 1 答案正确 2 3.00 ms 456 KB 2 答案正确 2 3.00 ms 496 KB 3 答案正确 1 3.00 ms 328 KB 4 答案正确 2 3.00 ms 324 KB
#include <iostream>
#include <bits/stdc++.h>
#include <string.h>
#include <stdio.h>
#include <vector>
#include <stdlib.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define dxeng(p) ((p>='a'&&p<='z')||(p>='A'&&p<='Z'))
#define CHECK(x,y) (x>=1&&x<=n&&y>=1&&y<=m)
#define ll long long int
#define wl() int t;cin >> t;getchar();while(t--)
#define s_c(s) scanf("%[^\n]",s)
using namespace std;
int ans = 0,bns = 0,x;
int a[10010][10010];
vector<int> c;
int lmax = 0;
int main(){
int n,m,sum = 0,num = 0;
cin >> n >> m;
rep(i,1,n){
cin >> x;
sum+=x;
num++;
if(sum == m) {
ans++;
bns+=num;
sum = 0,num = 0;
}
else if(sum > m) {
sum-=x;
num--;
}
}
cout << ans << " " << bns;
return 0;
}
7-2 用药统计 (20分)
上图是知乎上的一个问题:“在计算机中,有没有那种把很多病历导入,然后用计算机统计哪种药用的多的语言。?”虽然这个问题有错别字和标点符号错误,但好心的你还是帮他做一个吧 —— 给定 N 位病人病历中的用药纪录,请你统计被用的最多的那种药,并且列出其治疗过的疾病。
输入格式:
输入第一行给出正整数 N(≤104),为病历个数。随后 N 行,每行给出一条病历信息,格式如下:
疾病编号 K 药物编号1 药物编号2 …… 药物编号K
其中疾病编号是一个 4 位数字,题目保证每条病历中的疾病编号都是不同的;
K
是不超过 10 的正整数,为该疾病用药的种类数;药物编号是一个以MD
开头、后面跟 5 位数字的字符串。题目保证在一条病历中没有重复的药物编号。输出格式:
首先在第一行输出被用的最多的那种药的编号,及其被用的次数,其间以一个空格分隔。如果有并列,则只输出编号最小(即
MD
后那串数字最小)的那个。随后按照输入的顺序输出该药物治疗过的疾病的编号,每行一个。输入样例:
5 0012 3 MD10031 MD99132 MD42107 1024 2 MD99132 MD34821 2048 2 MD27845 MD10031 0149 2 MD34821 MD55802 0035 3 MD55802 MD99132 MD10031
输出样例:
MD10031 3 0012 2048 0035
评测结果
答案正确(20 分)
编译器输出
a.cpp: In function ‘int main()’: a.cpp:7:33: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] #define rep(i,a,b) for(int i=a;i<=b;i++) a.cpp:41:6: rep(i,0,a[index].bin.size()-1){ ~~~~~~~~~~~~~~~~~~~~~~~~~ a.cpp:41:2: note: in expansion of macro ‘rep’ rep(i,0,a[index].bin.size()-1){ ^~~测试点得分
测试点 结果 得分 耗时 内存 0 答案正确 10 24.00 ms 27844 KB 1 答案正确 1 22.00 ms 27840 KB 2 答案正确 1 22.00 ms 27840 KB 3 答案正确 1 22.00 ms 27840 KB 4 答案正确 2 60.00 ms 30648 KB 5 答案正确 5 67.00 ms 29888 KB
#include <iostream>
#include <bits/stdc++.h>
#include <string.h>
#include <stdio.h>
#include <vector>
#include <stdlib.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define dxeng(p) ((p>='a'&&p<='z')||(p>='A'&&p<='Z'))
#define CHECK(x,y) (x>=1&&x<=n&&y>=1&&y<=m)
#define ll long long int
#define wl() int t;cin >> t;getchar();while(t--)
#define s_c(s) scanf("%[^\n]",s)
using namespace std;
int ans = 0,bns = 0,x;
int b[1000010];
class A{
public:
vector<int> bin;
}a[1000010];
int lmax = 0;
int main(){
memset(b,0,sizeof(b));
int n;
int bing,cou,x;
cin >> n;
rep(i,1,n){
cin >> bing >> cou;
rep(j,1,cou){
char p;
cin >> p >> p >> x;
b[x]++;
a[x].bin.push_back(bing);
}
}
int max = -1,index = 0;
rep(i,0,100000){
if(b[i] > max) max = b[i],index = i;
}
printf("MD%05d %d\n",index,max);
rep(i,0,a[index].bin.size()-1){
printf("%04d\n",a[index].bin[i]);
}
return 0;
}
7-3 五彩斑斓的黑 (20分)
上面这张图是一条五彩斑斓的黑蛇。我们从头到尾扫描了蛇的身体,将获得的颜色 RGB 值顺序列出。下面就请你统计一下,这条五彩斑斓的黑蛇身上共有多少种不同的颜色,并且将每种不同的颜色按照它们第一次被扫描到的顺序输出。
输入格式:
输入首先在第一行中给出一个正整数 N(≤105),随后一行给出 N 个颜色的 RGB 值,每个颜色的格式为
RRR.GGG.BBB
,其中RRR
、GGG
、BBB
的值在区间 [0,255] 内。相邻颜色间以 1 个空格分隔。输出格式:
在第一行中输出不同颜色的数量。第二行按照输入相同的格式、每种颜色第一次被扫描到的顺序输出各种不同颜色的值。相邻颜色间以 1 个空格分隔,行首尾不得有多余空格。
输入样例:
7 000.000.000 255.255.255 000.000.000 000.123.072 000.000.000 000.000.000 000.123.072
输出样例:
3 000.000.000 255.255.255 000.123.072
评测结果
答案正确(20 分)
测试点得分
测试点 结果 得分 耗时 内存 0 答案正确 10 45.00 ms 65980 KB 1 答案正确 2 45.00 ms 65984 KB 2 答案正确 2 97.00 ms 65988 KB 3 答案正确 3 141.00 ms 68652 KB 4 答案正确 3 152.00 ms 68520 KB
#include <iostream>
#include <bits/stdc++.h>
#include <string.h>
#include <stdio.h>
#include <vector>
#include <stdlib.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define dxeng(p) ((p>='a'&&p<='z')||(p>='A'&&p<='Z'))
#define CHECK(x,y) (x>=1&&x<=n&&y>=1&&y<=m)
#define ll long long int
#define wl() int t;cin >> t;getchar();while(t--)
#define s_c(s) scanf("%[^\n]",s)
using namespace std;
int a[256][256][256];
int lmax = 0;
int main(){
int n,ans = 0;
vector<int> rr,gg,bb;
memset(a,0,sizeof(a));
cin >> n;
char p;
int r,g,b;
rep(i,1,n){
cin >> r >> p >> g >> p >> b;
if(a[r][g][b] == 0){
ans++;
rr.push_back(r);
gg.push_back(g);
bb.push_back(b);
}
a[r][g][b]++;
}
cout << ans << endl;
rep(i,1,ans){
if(i!=1) cout << " ";
printf("%03d.%03d.%03d",rr[i-1],gg[i-1],bb[i-1]);
}
return 0;
}
7-4 假新闻 (20分)
所有的新闻网站都是有自己立场的,只是有些能比较好地平衡事实与己见。“假新闻”是指为了误导大众对真实事件的理解而做的故意歪曲事实的报导。
为了甄别新闻媒体是否属于假新闻媒体,我们可以注意观察若干不同的新闻网站对同一个重要事件的报导。甄别算法如下:
- 首先选择 N 家新闻网站。
- 对每一个重要的事件,扫描每家网站,用不同的整数表示报导的不同观点。
- 定义网站 i 报导假新闻的可能性为 Fi=ni/N,其中 ni 是与网站 i 持不同观点的其它新闻网站数量。
- 找出报导假新闻可能性最大的一家或几家网站。
- 对每家网站,统计其成为最可能的假新闻网站的次数,最后找出次数最多的那家,就是在最多情况下最可能报导假新闻的网站。
输入格式:
输入第一行给出两个正整数 N (≤104),为关注的新闻网站的数量;以及 M(≤100),为关注的重要事件的数量。随后 M 行,每行按以下格式给出各个新闻网站报导的观点:
R1 R2 ... RN
其中 Ri 是区间 [−104,104] 内的整数,表示网站 i 的观点。
输出格式:
在一行中输出在最多情况下最可能报导假新闻的网站的编号。题目保证解是唯一的。
输入样例:
4 6 4 2 7 7 1 1 1 3 2 9 9 5 -1 -1 -1 -1 -2 2 -2 2 1 1 3 4
输出样例:
4
样例说明:
每次中大事件对应的 Fi 的值如下:
事件 1: 3/4 3/4 2/4 2/4 --> 1 和 2 疑似 事件 2: 1/4 1/4 1/4 3/4 --> 4 疑似 事件 3: 3/4 2/4 2/4 3/4 --> 1 和 4 疑似 事件 4: 0 0 0 0 --> 全都疑似 事件 5: 2/4 2/4 2/4 2/4 --> 全都疑似 事件 6: 2/4 2/4 3/4 3/4 --> 3 和 4 疑似
所以只有 4 号网站有 5 次都被列为最大疑似,其它都只有 3 或 4 次。
评测结果
答案正确(20 分)
编译器输出
a.cpp: In function ‘int main()’: a.cpp:43:7: warning: ‘index’ may be used uninitialized in this function [-Wmaybe-uninitialized] cout << index; ~~~~~^~~~~~~~测试点得分
测试点 结果 得分 耗时 内存 0 答案正确 11 3.00 ms 584 KB 1 答案正确 1 2.00 ms 456 KB 2 答案正确 5 238.00 ms 584 KB 3 答案正确 3 153.00 ms 588 KB
#include <iostream>
#include <bits/stdc++.h>
#include <string.h>
#include <stdio.h>
#include <vector>
#include <stdlib.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define dxeng(p) ((p>='a'&&p<='z')||(p>='A'&&p<='Z'))
#define CHECK(x,y) (x>=1&&x<=n&&y>=1&&y<=m)
#define ll long long int
#define wl() int t;cin >> t;getchar();while(t--)
#define s_c(s) scanf("%[^\n]",s)
using namespace std;
int a[10010],b[20020],c[10010];
int lmax = 0;
int main(){
memset(c,0,sizeof(c));
int n,m,x;
cin >> n >> m;
while(m--){
memset(b,0,sizeof(b));
rep(i,1,n){
cin >> x;
x+=10000;
a[i] = x;
b[x]++;
}
int max = -1;
rep(i,1,n){
int num = n - b[a[i]];
if(num > max) max = num;
}
rep(i,1,n){
int num = n - b[a[i]];
if(num == max) c[i]++;
}
}
int nmax = -1,index;
rep(i,1,n){
if(c[i] > nmax) nmax = c[i],index = i;
}
cout << index;
return 0;
}
7-5 静态链表的秩 (25分)
静态链表是指将一个有 n 个结点的链表存放在一个有 n 个单元的数组里,每个数组单元包含一个整型的
data
域和一个next
指针,指针里存的是链表下一个结点在数组里对应的单元下标。题目保证给出的链表是一个线性表,即除了第一个结点外,每个结点有其唯一的前驱结点;除了最后一个结点外,每个结点有其唯一的后继结点。你的任务是将这个链表上的结点顺序编号,即从第一个结点开始,从 1 到 n 给每个结点顺次编号 —— 这个编号就叫结点的“秩”。
输入格式:
输入第一行给出一个正整数 n (≤105),为链表中的结点个数。第二行给出 n 个数字,第 i (i=0,⋯,n−1) 个数字对应数组第 i 个单元存储的 next(i) 的值,空指针用 −1 表示。数字间以空格分隔。
输出格式:
在一行中输出 n 个数字,第 i (i=0,⋯,n−1) 个数字对应第 i 个单元存储的结点在链表中的秩。数字间以 1 个空格分开,行首尾不得有多余空格。
输入样例:
5 3 -1 4 1 0
输出样例:
3 5 1 4 2
样例说明:
输入的链表为 2->4->0->3->1->空。于是第 0 个单元所存的结点的秩是 3,因为它是链表中的第 3 个结点;第 1 个单元所存的结点的秩是 5,因为它是链表中的第 5 个结点;以此类推。
评测结果
答案正确(25 分)
测试点得分
测试点 结果 得分 耗时 内存 0 答案正确 14 3.00 ms 440 KB 1 答案正确 1 3.00 ms 476 KB 2 答案正确 2 32.00 ms 2248 KB 3 答案正确 2 32.00 ms 2244 KB 4 答案正确 3 32.00 ms 2236 KB 5 答案正确 3 32.00 ms 2116 KB
#include <iostream>
#include <bits/stdc++.h>
#include <string.h>
#include <stdio.h>
#include <vector>
#include <stdlib.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define dxeng(p) ((p>='a'&&p<='z')||(p>='A'&&p<='Z'))
#define CHECK(x,y) (x>=1&&x<=n&&y>=1&&y<=m)
#define ll long long int
#define wl() int t;cin >> t;getchar();while(t--)
#define s_c(s) scanf("%[^\n]",s)
using namespace std;
int a[100010],b[100010],c[100010];
int lmax = 0;
int main(){
int n,x,ans = 0;
cin >> n;
rep(i,1,n){
cin >>x;
x++;
a[x] = i;
}
int last = a[0];
rep(i,1,n){
b[ans++] = last;
last = a[last];
}
rep(i,0,ans-1) b[i]--;
per(i,ans-1,0){
c[b[i]] = ans - i;
}
rep(i,0,ans-1){
if(i!=0) cout << " ";
cout << c[i];
}
return 0;
}