ACM | ACM Test 240104
1001 大笨钟
微博上有个自称“大笨钟V”的家伙,每天敲钟催促码农们爱惜身体早点睡觉。不过由于笨钟自己作息也不是很规律,所以敲钟并不定时。一般敲钟的点数是根据敲钟时间而定的,如果正好在某个整点敲,那么“当”数就等于那个整点数;如果过了整点,就敲下一个整点数。另外,虽然一天有24小时,钟却是只在后半天敲1~12下。例如在23:00
敲钟,就是“当当当当当当当当当当当”,而到了23:01
就会是“当当当当当当当当当当当当”。在午夜00:00
到中午12:00
期间(端点时间包括在内),笨钟是不敲的。
下面就请你写个程序,根据当前时间替大笨钟敲钟。
输入格式:
输入第一行按照hh:mm
的格式给出当前时间。其中hh是小时,在00到23之间;mm是分钟,在00到59之间。
输出格式:
根据当前时间替大笨钟敲钟,即在一行中输出相应数量个Dang
。如果不是敲钟期,则输出:Only hh:mm. Too early to Dang.
其中hh:mm
是输入的时间。
输入样例1:
19:05
输出样例1:
DangDangDangDangDangDangDangDang
输入样例2:
07:05
输出样例2:
Only 07:05. Too early to Dang.
Code
#include<bits/stdc++.h>
using namespace std;
int main(){
int hh,mm;
scanf("%d:%d",&hh,&mm);
if(hh<=11 || (hh==12 && mm==0)){
printf("Only %02d:%02d. Too early to Dang.",hh,mm);
}else{
if(mm==0){
for(int i=0;i<hh-12;i++){
cout<<"Dang";
}
cout<<endl;
}else{
for(int i=0;i<hh+1-12;i++){
cout<<"Dang";
}
cout<<endl;
}
}
return 0;
}
1002 宇宙无敌加法器
地球人习惯使用十进制数,并且默认一个数字的每一位都是十进制的。而在 PAT 星人开挂的世界里,每个数字的每一位都是不同进制的,这种神奇的数字称为“PAT数”。每个 PAT 星人都必须熟记各位数字的进制表,例如“……0527”就表示最低位是 7 进制数、第 2 位是 2 进制数、第 3 位是 5 进制数、第 4 位是 10 进制数,等等。每一位的进制 d 或者是 0(表示十进制)、或者是 [2,9] 区间内的整数。理论上这个进制表应该包含无穷多位数字,但从实际应用出发,PAT 星人通常只需要记住前 20 位就够用了,以后各位默认为 10 进制。
在这样的数字系统中,即使是简单的加法运算也变得不简单。例如对应进制表“0527”,该如何计算“6203 + 415”呢?我们得首先计算最低位:3 + 5 = 8;因为最低位是 7 进制的,所以我们得到 1 和 1 个进位。第 2 位是:0 + 1 + 1(进位)= 2;因为此位是 2 进制的,所以我们得到 0 和 1 个进位。第 3 位是:2 + 4 + 1(进位)= 7;因为此位是 5 进制的,所以我们得到 2 和 1 个进位。第 4 位是:6 + 1(进位)= 7;因为此位是 10 进制的,所以我们就得到 7。最后我们得到:6203 + 415 = 7201。
输入格式:
输入首先在第一行给出一个 \(N\) 位的进制表\((0 < N ≤ 20)\),以回车结束。 随后两行,每行给出一个不超过 \(N\) 位的非负的 PAT 数。
输出格式:
在一行中输出两个 PAT 数之和。
输入样例:
30527
06203
415
输出样例:
7201
Code
#include<bits/stdc++.h>
using namespace std;
int main(){
string table,str1,str2;
int a[30],b[30],ans[30],cura=0,curb=0,cur=0;
cin>>table>>str1>>str2;
int len=table.length();
// bool flag=true;
for(int i=str1.length()-1;i>=0;i--){
a[cura]=str1[i]-'0';
// if(flag && a[cura]==0) cur--;
// if(flag && a[cura]!=0) flag=false;
cura++;
}
while(a[cura-1]==0){
cura--;
}
// for(int i=0;i<cura;i++){
// cout<<a[i]<<" ";
// }
// flag=true;
for(int i=str2.length()-1;i>=0;i--){
b[curb]=str2[i]-'0';
// if(flag && b[curb]==0) cur--;
// if(flag && b[curb]!=0) flag=false;
curb++;
}
while(b[curb-1]==0){
curb--;
}
int digits[30],curd=0;
memset(digits,10,sizeof(digits));
for(int i=table.length()-1;i>=0;i--){
if(table[i]=='0'){
digits[curd]=10;
}else{
digits[curd]=table[i]-'0';
}
curd++;
}
// for(int i=0;i<curd;i++){
// cout<<digits[i]<<" ";
// }
int put=0,temp=0;
while(cur<min(cura,curb)){
temp=a[cur]+b[cur]+put;
ans[cur]=temp%digits[cur];
put=temp/digits[cur];
cur++;
}
if(cura==cur){
//process b
while(cur<curb){
temp=b[cur]+put;
ans[cur]=temp%digits[cur];
put=temp/digits[cur];
cur++;
}
}else{
while(cur<cura){
temp=a[cur]+put;
ans[cur]=temp%digits[cur];
put=temp/digits[cur];
cur++;
}
}
if(put!=0){
ans[cur]=put;
cur++;
}
for(int i=cur-1;i>=0;i--){
cout<<ans[i];
}
cout<<endl;
return 0;
}
1003 到底是不是太胖了
据说一个人的标准体重应该是其身高(单位:厘米)减去100、再乘以0.9所得到的公斤数。真实体重与标准体重误差在10%以内都是完美身材(即 | 真实体重 − 标准体重 | < 标准体重×10%)。已知市斤是公斤的两倍。现给定一群人的身高和实际体重,请你告诉他们是否太胖或太瘦了。
输入格式:
输入第一行给出一个正整数\(N(≤ 20)\)。随后N行,每行给出两个整数,分别是一个人的身高\(H(120 < H < 200;\)单位:厘米)和真实体重\(W(50 < W ≤ 300;\)单位:市斤),其间以空格分隔。
输出格式:
为每个人输出一行结论:如果是完美身材,输出You are wan mei!
;如果太胖了,输出You are tai pang le!
;否则输出You are tai shou le!
。
输入样例:
3
169 136
150 81
178 155
输出样例:
You are wan mei!
You are tai shou le!
You are tai pang le!
Code1
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,h,w;
double standard;
cin>>n;
while(n--){
cin>>h>>w;
standard=(h-100)*0.9*2;
if(w>=standard*0.9 && w<=standard*1.1){
cout<<"You are wan mei!"<<endl;
}else if(w<standard*0.9){
cout<<"You are tai shou le!"<<endl;
}else{
cout<<"You are tai pang le!"<<endl;
}
}
return 0;
}
Code2
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,h,w;
double standard;
cin>>n;
while(n--){
cin>>h>>w;
standard=(h-100)*0.9*2;
if(abs(w-standard)<standard*0.1){
cout<<"You are wan mei!"<<endl;
}else if(w<=standard){
cout<<"You are tai shou le!"<<endl;
}else if(w>=standard){
cout<<"You are tai pang le!"<<endl;
}
}
return 0;
}
1005 抢红包
没有人没抢过红包吧…… 这里给出N个人之间互相发红包、抢红包的记录,请你统计一下他们抢红包的收获。
输入格式:
输入第一行给出一个正整数 \(N(≤10^4)\) ,即参与发红包和抢红包的总人数,则这些人从1到N编号。随后N行,第i行给出编号为i的人发红包的记录,格式如下:
K N_1 P_1 ⋯ N_K P_K
其中 \(K(0≤K≤20)\) 是发出去的红包个数,\(N_i\) 是抢到红包的人的编号, \(P_i(>0)\) 是其抢到的红包金额(以分为单位)。注意:对于同一个人发出的红包,每人最多只能抢1次,不能重复抢。
输出格式:
按照收入金额从高到低的递减顺序输出每个人的编号和收入金额(以元为单位,输出小数点后2位)。每个人的信息占一行,两数字间有1个空格。如果收入金额有并列,则按抢到红包的个数递减输出;如果还有并列,则按个人编号递增输出。
输入样例:
10
3 2 22 10 58 8 125
5 1 345 3 211 5 233 7 13 8 101
1 7 8800
2 1 1000 2 1000
2 4 250 10 320
6 5 11 9 22 8 33 7 44 10 55 4 2
1 3 8800
2 1 23 2 123
1 8 250
4 2 121 4 516 7 112 9 10
输出样例:
1 11.63
2 3.63
8 3.63
3 2.11
7 1.69
6 -1.67
9 -2.18
10 -3.26
5 -3.26
4 -12.32
Code
#include<bits/stdc++.h>
using namespace std;
bool cmp(tuple<int,int,int>& a,tuple<int,int,int>& b){
if(get<1>(a) == get<1>(b)){
if(get<2>(a) == get<2>(b))
return get<0>(a) < get<0>(b);
else
return get<2>(a) > get<2>(b);
}
return (get<1>(a) > get<1>(b));
}
int main(){
int n;
cin>>n;
vector<tuple<int,int,int>> v(n);
for(int i=0;i<n;i++){
get<0>(v[i])=i+1;
get<1>(v[i])=0;
}
for(int i=0;i<n;i++){
int t;
cin>>t;
get<2>(v[i])=t;
while(t--){
int p,q;
cin>>p>>q;
get<1>(v[p-1])+=q;
get<1>(v[i])-=q;
}
}
sort(v.begin(),v.end(),cmp);
for(int i=0;i<n;i++){
printf("%d %.2lf\n",get<0>(v[i]),get<1>(v[i])/100.0);
}
return 0;
}
1006 社交集群
当你在社交网络平台注册时,一般总是被要求填写你的个人兴趣爱好,以便找到具有相同兴趣爱好的潜在的朋友。一个“社交集群”是指部分兴趣爱好相同的人的集合。你需要找出所有的社交集群。
输入格式:
输入在第一行给出一个正整数 \(N(≤1000)\),为社交网络平台注册的所有用户的人数。于是这些人从 \(1\) 到 \(N\) 编号。随后 \(N\) 行,每行按以下格式给出一个人的兴趣爱好列表:
\(K_i: h_i[1] h_i[2] ... h_i[K_i]\)
其中 \(K_i(>0)\) 是兴趣爱好的个数,\(h_i[j]\) 是第\(j\)个兴趣爱好的编号,为区间 \([1, 1000]\) 内的整数。
输出格式:
首先在一行中输出不同的社交集群的个数。随后第二行按非增序输出每个集群中的人数。数字间以一个空格分隔,行末不得有多余空格。
输入样例:
8
3: 2 7 10
1: 4
2: 5 3
1: 4
1: 3
1: 4
4: 6 8 1 5
1: 4
输出样例:
3
4 3 1
Code
#include<bits/stdc++.h>
using namespace std;
int p[1009], user[1009], hobby[1009];
int find(int x){
if(p[x] == x){
return x;
}
return p[x] = find(p[x]);
}
void merge(int x, int y){
int xx = find(x), yy = find(y);
if(xx != yy){
p[yy] = xx;
}
}
bool cmp(int x, int y){
return x > y;
}
int main()
{
for(int i=1; i<=1000; i++){
p[i] = i;
}
int n,k,h,num=0;
char ch;
cin >> n;
for(int i=1; i<=n; i++){
cin >> k >> ch >> user[i];
for(int j=1; j<=k-1; j++){
cin >> h;
merge(user[i], h);
}
}
for(int i=1; i<=n; i++){
hobby[find(user[i])]++;
}
for(int i=1; i<=1000; i++){
if(hobby[i]!=0) num++;
}
sort(hobby, hobby+1001, cmp);
cout << num << endl;
for(int i=0; i<num; i++){
if(i!=0) cout << " ";
cout << hobby[i];
}
return 0;
}