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;
}

ACM | ACM Test 240104
https://acm.nanyan.cc/posts/b6dd.html
作者
nanyan
发布于
2024年1月4日
许可协议