0


pta 520 钻石争霸赛 2022 (题目+个人题解)

整体个人评价: 总体上题目不难,还是挺有趣的。

个人体验很不错,这就很521~

当然本人水平也还是不足的啦,当时一个小时只写了81分,思路是有的,但是代码实现嘛……还有所欠缺

以下是个人娱乐赛时写的原代码(没改过)+ 跟所有题目的思路

7-1 520表白

在 520 这个日子里,拼题 A 请你实现一个小功能,帮助用户向自己喜欢的数字表白。

输入格式:

输入在一行中给出一个不超过 1000 的正整数 N,是用户最喜欢的一个数字。

样输入样例:

233

输出样例:

233! 520!
#include<iostream>
using namespace std;
int main(){
    int a;
    cin >> a;
    printf("%d! 520!",a);
    return 0;
}

-------------------------------------------------------------------------------------------------------------------

7-2 分糖豆

N 个宝宝分 M 颗 m&m 糖豆,如果每人分 K 个,够不够分呀?

输入格式:

输入在一行中给出 3 个正整数,分别是 N(不超过 100),是宝宝们的总人数;M(不超过 1000),是糖豆的总颗数;K(不超过 10),是要分给每个宝宝的糖豆数。

输出格式:

如果每人 K 个正好能够分完,输出

zheng hao mei ren K!

;如果分完了还剩 X 颗糖豆,则输出

hai sheng X!

;如果不够分的,还差 X 颗糖豆,则输出

hai cha X!

输入样例 1:

10 50 5

输出样例 1:

zheng hao mei ren 5!

输入样例 2:

12 30 2

输出样例 2:

hai sheng 6!

输入样例 3:

15 40 3

输出样例 3:

hai cha 5!
#include<iostream>
using namespace std;
int main(){
    int a,b,c;
    cin >> a >> b >> c;
    if(a*c==b) printf("zheng hao mei ren %d!",c);
    else if(a*c>b) printf("hai cha %d!",a*c-b);
    else printf("hai sheng %d!",b-a*c);
    return 0;
}

-------------------------------------------------------------------------------------------------------------------

7-3 约会App

在 520 这个日子里,没有比开发一个约会 App 更合适做的事情了。这个软件的需求很简单,用户输入自己的性别、想要约会的异性的年龄范围 [a,b]、身高范围 [c,d],你要帮用户筛选出系统中满足其约会条件的所有异性。注意:性别、年龄、身高的要求必须全都符合要求才可以。

输入格式:

输入第一行首先给出一个用户自己输入的信息,格式如下:

性别 a b c d

其中

性别

为 0 表示女性,1 表示男性,是该用户自己的性别;后面四个数字依次表示该用户想要约会的异性的年龄下限、年龄上限、身高下限、身高上限 —— 注意这里的范围都是闭区间。

随后一行给出一个正整数 N≤100,随后 N 行,每行给出一位系统中登记的约会对象的信息,格式如下:

性别 年龄 身高

这里保证年龄和身高(包括上、下限)均为不超过 200 的正整数,同行数字间以 1 个空格分隔。

输出格式:

按照输入的顺序,输出每个满足用户约会条件的约会对象的信息,输出格式与输入格式相同。题目保证至少有一个人可以被输出。

输入样例:

1 20 25 160 175
6
0 28 165
1 21 170
0 25 160
0 22 180
1 20 175
0 20 175

输出样例:

0 25 160
0 20 175

ps 哈哈没想到一下子vector都用上了,其实数组写更快,但是平时这样写习惯了

#include<bits/stdc++.h>
using namespace std;
struct Person{
    int sex,age,high;
};
int main()
{
    vector<Person> man;
    vector<Person> woman;
    int sex,age_min,age_max,high_min,high_max,num;
    Person a;
    cin >> sex >> age_min >> age_max >> high_min >> high_max >> num;
    while (num--){
        cin >> a.sex >> a.age >> a.high;
        if(a.sex==1) man.push_back(a);
        else woman.push_back(a);
    }

    vector<Person> key;
    if(sex==1){
        for(auto & z : woman){
            if(z.age >= age_min && z.age <= age_max && z.high <=high_max && z.high >= high_min){
                key.push_back(z);
            }
        }
    }else{
        for(auto & z : man){
            if(z.age >= age_min && z.age <= age_max && z.high <=high_max && z.high >= high_min){
                key.push_back(z);
            }
        }
    }

    for(auto & z : key){
        cout << z.sex <<" " << z.age << " " << z.high << endl;
    }
    return 0;
}

-------------------------------------------------------------------------------------------------------------------

7-4 关于奇数的等式

给定任一正奇数 n>3 和一个解的上界 m>3,求三个正奇数 x、y、z,满足 0<x<y<z≤m 且有等式 3/n=1/x+1/y+1/z。

输入格式:

输入给出正奇数 3<n<400 和解的上界 m≤1000。

输出格式:

在一行中输出给定范围内最小的一组解

x y z

(即存在多组解时取最小的

x

,并列时取最小的

y

)。数字间以 1 个空格分隔,行首尾不得有多余空格。

如果给定范围内无解,则输出

No solution in (3, m].

其中

m

是给定的上界。

输入样例 1:

27 500

输出样例 1:

11 55 495

ps : 这题本人稍微通分了一下,就是俩边互乘分母,怕直接用double判断精度上可能会出错(代码里面的循环其实理论上第一层的循环次数还要减2,第二层减1,这样才完全正确,但提交的时候测试点全过了,嘿嘿那就不管那么多了)

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,flag,x,y,z;
    bool f = false;
    cin >> n >> flag;
    for( x=1;x<flag;x+=2){
        for( y=x+2;y<flag;y+=2){
            for( z=y+2;z<=flag;z+=2){

                if(3*x*y*z==n*(x*y+x*z+y*z)){
                    f = true;
                    goto end;
                }
            }
        }
    }

    end :

    if(f){
        cout << x << " " << y << " " << z;
    }else{
        printf("No solution in (3, %d].",flag);
    }

    return 0;
}

---------------------------------------------------------------------------------------------------------------------------------

7-5 我侬数

元初的中国书画大家赵孟頫的妻子管道升曾经写过一首脍炙人口的《我侬词》,词中道:“把一块泥,捻一个你,塑一个我。将咱们两个一齐打破,用水调和。再捏一个你,再塑一个我。我泥中有你,你泥中有我。”

给定一对正整数 A 和 B,将它们的各位数字收集到一起,再重新分成两个数 A′ 和 B′,我们称这样的 A′ 和 B′ 互为基于 A 和 B 的“我侬数“。本题就请你判断任一对数字是否是基于给定 A 和 B 的“我侬数“。

输入格式:

输入首先在第一行中给出两个不超过 104 位的正整数 A 和 B,为“我侬数“的基础数。随后每行给出一对不超过 2×104 位的正整数 A′ 和 B′。数字间以 1 个空格分隔。

输入以一对 0 结束,这一对 0 不要处理。题目保证至少有一对需要判定的数字。

输出格式:

对每一对 A′ 和 B′,判断其是否是基于给定 A 和 B 的“我侬数“。如果是,则在一行中输出

Yes

,否则输出

No

注意:所有数字均不考虑前导 0。例如 A=101,B=2021,则我们不能判定 012 和 0121 为“我侬数“。

输入样例:

521212577999 21100008482136
521212577999 21100008482136
00210908482136 512121257799
123456789012597890 11100222
786238645254 19024781758903
21100008482136 521212577999
90 52121257792110008482136
0 0

输出样例:

Yes
No
Yes
No
Yes
No

ps : 这题就是字符串处理。。。就是读题可能绕了一下

#include<bits/stdc++.h>
using namespace std;
int main()
{
    string a,b;
    int key[11]={0};
    for(int z=0;z<2;z++){
        cin >> a;
        int len = 0;
        while (len < a.size() && a[len]=='0') len++;
        while (len<a.size()){
            key[a[len]-48]++;
            len ++;
        }
    }

    while (true){
        bool f = true;
        int flag[11]={0};
        cin >> a >> b;
        if(a.size()==1 && b.size()==1 && a[0]=='0' && b[0]=='0'){
            break;
        }
        int len = 0;
        while (len < a.size() && a[len]=='0') len++;
        while (len<a.size()){
            flag[a[len]-48]++;
            len ++;
        }
        len = 0;
        while (len < b.size() && b[len]=='0') len++;
        while (len<b.size()){
            flag[b[len]-48]++;
            len ++;
        }

        for(int z1=0;z1<10;z1++) if(key[z1]!=flag[z1]){
            f = false;
                break;
        }
        if(f) cout << "Yes" << endl;
        else cout << "No" << endl;

    }

    return 0;
}

---------------------------------------------------------------------------------------------------------------------------------

7-6 非诚勿扰

“非诚勿扰”是江苏台一款非常受欢迎的相亲节目,台上的女嘉宾们可以从出场的男嘉宾中选择自己喜欢的牵手离开。问题是怎样才能选到最适合自己的男嘉宾呢?这是个概率问题。

解决这个问题有一种随机算法:假设女嘉宾知道自己最多能在台上录几期节目,也就知道自己最多能见到 N 位男嘉宾,那么她可以选择一个随机数 R(<N),对她见到的前 R 位男嘉宾,一个都不牵,只是以他们中最合适的那位作为一个标准,从第 R+1 位男嘉宾开始,只要遇到一个比标准更合适的,就决定牵手。理论上可以证明,当 R=N/e (其中 e 是自然常数,约等于 2.718)时,这样做能牵手最合适的男嘉宾的概率最高。

本题就请你根据男嘉宾的出场顺序,预测一下女嘉宾会牵手哪一位。

输入格式:

输入首先在第一行中给出正整数 N(3≤N≤104),即男嘉宾的数量。第二行给出 N 个互不相同的正整数,第 i 个数字表示第 i 位男嘉宾在女嘉宾心目中的得分。数字均不超过 105,之间以空格分隔。

输出格式:

女嘉宾将以 R=⌊N/e⌋ 为线,采用题面中描述的算法选择牵手的男嘉宾。这里我们取 e=2.718。请在一行中输出她牵手的男嘉宾的序号和真正最适合她的男嘉宾的序号(从 1 开始),数字间以 1 个空格分隔。

如果她一直没有遇到比标准更合适的人,就会独自离开,此时对应的序号输出为

0

输入样例 1:

10
23 84 15 29 17 56 85 40 91 28

输出样例 1:

7 9

输入样例 2:

10
56 85 17 23 84 15 29 40 31 28

输出样例 2:

0 2

** ps : 这题看上去还是很简单的,不过本人愣是出了点意外,俩个输出一个对7分,一个对13,对错的测试点刚好想反,当时懵了一下,选了给13分的直接看最后一题去了,现在笑起来要是最后多一个为0判断估计能过**

(13分)

#include<bits/stdc++.h>
using namespace std;
int main()
{
    double e = 2.718;
    int R,N;
    long score[10001];
    cin >> N;
    R = N*1.0/e;
    int max = 1,flag=0;

    for(int z=1;z<=R;z++){
        cin >> score[z];
        if(score[z]>score[max]) max = z;
    }

    bool f = false;
    for(int z=R+1;z<=N;z++){
        cin >> score[z];
        if(score[z]>score[max]){
            flag=z;
            break;
        }
    }
    
//     printf("%d %d",flag,max);
    printf("%d %d",flag,max+flag);
    return 0;
}

--------------------------------------------------------------------------------------------------------------------------------

7-7 新式六合彩

新式六合彩跟传统六合彩其实没有半点关系,只是姥姥为了出题杜撰出来的一种玩法——每位玩家可以下注一个六位数,如果跟开出来的幸运六位数最接近就可以获奖(所谓最接近,是指该数字与幸运数之差的绝对值最小)。

但规则如果这么简单就没什么可玩的了…… 我们把规则搞复杂一点:首先创建一个有 n×m 个格子的矩阵,保证格子总数不小于玩家总数,可以把所有玩家下注的数字随机放进格子里,每个格子最多放一个。然后我们随机生成一个幸运行号 r (1≤r≤n)和幸运列号 c (1≤c≤m),再随机生成一个幸运六位数。中奖者是第 r 行和第 c 列的所有六位数中与幸运数最接近的那个数字的主人。

本题就请你写个程序实现这个抽奖功能。

输入格式:

输入第一行给出 2 个正整数 n 和 m(1≤n,m≤1000),随后 n 行,每行给出 m 个数字,对应该位置格子里玩家下注的数字。如果这个格子是空的,就用 −1 表示。最后一行给出幸运行号 r、幸运列号 c 和幸运六位数。同行数字间以空格分隔。

注意:行号从上向下递增,列号从左向右递增,均从 1 开始计数。

输出格式:

按照

(行号:列号)

的格式输出中奖者的位置。如果中奖者不唯一,则按照首先在幸运行中从左到右,然后在幸运列中从上到下的顺序输出,每行输出一位中奖者的位置。注意同一个位置只能输出一次。题目保证至少存在一位中奖者。

输入样例:

4 5
233333 000001 -1 888888 666666
001010 369624 777888 -1 999999
480735 100000 591846 369623 123123
456456 591846 000000 501000 233333
2 3 480735

输出样例:

(2:2)
(3:3)

PS :当时看剩下时间只有20分钟多点,就挑了分高的最后一题写了,这题没看,现在看一下思路还是很清晰的。

思路 : 数组读入以后对要求的行列开始比较取绝对值最小即可(注意排名并列),结果储存的时候可以俩个数组(或一个vector+数据结构)记录所在位置,如果遇到比当前绝对值小的vector.clear之后继续存就行了

---------------------------------------------------------------------------------------------------------------------------------

7-8 521序列

所谓“521 序列”是指将一个原始整数序列 S 中的每个数字分别乘以 5、2、1 后形成的序列,例如 S= { 5, 2, 1 } 时,其对应的 521 序列就是 { 25, 10, 5, 10, 4, 2, 5, 2, 1 } —— 这里我们不要求这个序列一定具有某种顺序,即 521 序列中元素的顺序是可以打乱的。给定 S 后,计算其对应的 521 序列是很简单的。但给定一个 521 序列,恢复其对应的原始序列 S 就略微复杂一点了。本题就请你恢复任意给定的 521 序列的原始序列。

输入格式:

输入第一行给出正整数 N(<105),为 521 序列的长度。随后一行给出 N 个整数,即给定的 521 序列。所有数字的绝对值不超过 105,以空格分隔。

输出格式:

在一行中按照非递增序输出 521 序列对应的原始序列。数字间以 1 个空格分隔,行首尾不得有多余空格。

题目保证原始序列是存在的。

输入样例:

12
1 -5 10 -1 2 4 5 -2 5 25 10 2

输出样例:

5 2 1 -1

** 思路 : sort 排序(降序写的话), 接下来排序后的第一个数(n为正)肯定是下一个要输出数的5倍,那么下一个 要找的数就是n/52,再下一个是n/5,找到移出集合就行了,负数的话反着来判断。直接O(n)时间复杂度历遍的话最后可能会超时,可以用二分改进历遍,哈哈思路是跟上了,但代码实现还不行(⊙﹏⊙)の呃*

(13分比赛时候写的原码)(靠,要是下面那个对0的比较写成大于等于0,除了大数据的测试点应该都能过)

#include<bits/stdc++.h>
using namespace std;
bool cmp(long x,long y){
    return x >=y ;
}
int main()
{
    vector<long> num;
    vector<long> key;
    long N,a;
    cin >> N;

    for(long z=0;z<N;z++){
        scanf("%ld",&a);
        num.push_back(a);
    }

    sort(num.begin(),num.end(),cmp);
//    for(int z=0;z<N;z++){
//        cout << num[z] << endl;
//    }
    while (!num.empty()){

        if(num[0]>0){
            long flag = num[0]/5;
            key.push_back(flag);
            long f1=0,f2=0;
            for(long z=1;z<num.size();z++){
                if(f1==0 && num[z]==flag*2) f1 = z;
                else if(f2==0 && num[z]==flag*1) f2 = z;
                if(f1 && f2) break;
            }
            num.erase(num.begin());
            num.erase(num.begin()+f1-1);
            num.erase(num.begin()+f2-2);
        }else{
            long flag = num.back()/5;
            key.push_back(flag);
            long f1=0,f2=0;
            for(long z=num.size()-2;z>=0;z--){
                if(f1==0 && num[z]==flag*2) f1 = z;
                else if(f2==0 && num[z]==flag*1) f2 = z;
                if(f1!=0 && f2!=0) break;
            }
            num.erase(num.begin()+f2);
            num.erase(num.begin()+f1-1);
            num.erase(num.end()-1);
        }

    }

    cout << key[0];
    for(long z=1;z<key.size();z++){
        printf(" %ld",key[z]);
    }
    return 0;
}
标签: c++ 算法

本文转载自: https://blog.csdn.net/daybreak_alonely/article/details/124889311
版权归原作者 三块不一样的石头 所有, 如有侵权,请联系我们删除。

“pta 520 钻石争霸赛 2022 (题目+个人题解)”的评论:

还没有评论