2024PTA L1题(详细注释+测试点c++)

文章讲述了浙江大学陈越教授的编程题目,涉及基础算法、逻辑判断、数学应用(如持续性计算和九宫格规则检验)、实际场景模拟(如交通信号灯和牛肉面销售)等内容,展示了编程如何解决日常问题。
摘要由CSDN通过智能技术生成

目录

L1-097 编程解决一切

分数 5

作者 陈越

单位 浙江大学

编程解决一切 —— 本题非常简单,就请你直接在屏幕上输出这句话:“Problem? The Solution: Programming.”。

输入格式:

本题没有输入。

输出格式:

在一行中输出 Problem? The Solution: Programming.

输入样例:

输出样例:

Problem? The Solution: Programming.
#include<bits/stdc++.h>
using namespace std;
int main(){
    cout<<"Problem? The Solution: Programming.";
    return 0;
}

L1-098 再进去几个人

分数 5

作者 陈越

单位 浙江大学

bh.png


数学家、生物学家和物理学家坐在街头咖啡屋里,看着人们从街对面的一间房子走进走出。他们先看到两个人进去。时光流逝。他们又看到三个人出来。
物理学家:“测量不够准确。”
生物学家:“他们进行了繁殖。”
数学家:“如果现在再进去一个人,那房子就空了。”
下面就请你写个程序,根据进去和出来的人数,帮数学家算出来,再进去几个人,那房子就空了。

输入格式:

输入在一行中给出 2 个不超过 100 的正整数 A 和 B,其中 A 是进去的人数,B 是出来的人数。题目保证 B 比 A 要大。

输出格式:

在一行中输出使得房子变空的、需要再进去的人数。

输入样例:

4 7

输出样例:

3

#include<bits/stdc++.h>
using namespace std;
int main(){
    int a,b;
    cin>>a>>b;
    cout<<b-a;
    return 0;
}

L1-099 帮助色盲

作者 陈越

单位 浙江大学

sm.jpg

在古老的红绿灯面前,红绿色盲患者无法分辨当前亮起的灯是红色还是绿色,有些聪明人通过路口的策略是这样的:当红灯或绿灯亮起时,灯的颜色无法判断,但前方两米内有同向行走的人,就跟着前面那人行动,人家走就跟着走,人家停就跟着停;如果当前是黄灯,那么很快就要变成红灯了,于是应该停下来。麻烦的是,当灯的颜色无法判断时,前方两米内没有人……
本题就请你写一个程序,通过产生不同的提示音来帮助红绿色盲患者判断当前交通灯的颜色;但当患者可以自行判断的时候(例如黄灯或者前方两米内有人),就不做多余的打扰。具体要求的功能为:当前交通灯为红灯或绿灯时,检测其前方两米内是否有同向行走的人 —— 如果有,则患者自己可以判断,程序就不做提示;如果没有,则根据灯的颜色给出不同的提示音。黄灯也不需要给出提示。

输入格式:

输入在一行中给出两个数字 A 和 B,其间以空格分隔。其中 A 是当前交通灯的颜色,取值为 0 表示红灯、1 表示绿灯、2 表示黄灯;B 是前方行人的状态,取值为 0 表示前方两米内没有同向行走的人、1 表示有。

输出格式:

根据输入的状态在第一行中输出提示音:dudu 表示前方为绿灯,可以继续前进;biii 表示前方为红灯,应该止步;- 表示不做提示。在第二行输出患者应该执行的动作:move 表示继续前进、stop 表示止步。

输入样例 1:

0 0

输出样例 1:

biii
stop

输入样例 2:

1 1

输出样例 2:

-
move
#include<bits/stdc++.h>
using namespace std;
int main(){
    int deng,ren;
    cin>>deng>>ren;
    if(ren){        //有人的时候
        cout<<"-\n";
        if(deng==1) cout<<"move";    //绿灯,人走车也走
        else cout<<"stop";        //红灯,人不走车不走
    }
    else {            //没人的时候
        if(deng==1)    cout<<"dudu\nmove";    //绿灯就dudu
        else if(deng==0)cout<<"biii\nstop";   //红灯就biii
        else cout<<"-\nstop";    //他只是红绿色盲,黄色还是看得出的
    }
    return 0;
}

L1-100 四项全能

作者 陈越

单位 浙江大学

ti.jpg


新浪微博上有一个帖子给出了一道题:全班有 50 人,有 30 人会游泳,有 35 人会篮球,有 42 人会唱歌,有 46 人会骑车,至少有( )人四项都会。
发帖人不会做这道题,但是回帖有会做的:每一个才艺是一个技能点,一共是 30 + 35 + 42 + 46 = 153 个技能点,50 个人假设平均分配,每人都会 3 个技能那也只有 150,所以至少有 3 人会四个技能。
本题就请你写个程序来自动解决这类问题:给定全班总人数为 n,其中有 m 项技能,分别有 k1​、k2​、……、km​ 个人会,问至少有多少人 m 项都会。

输入格式:

输入在第一行中给出 2 个正整数:n(4≤n≤1000)和 m(1<m≤n/2),分别对应全班人数和技能总数。随后一行给出 m 个不超过 n 的正整数,其中第 i 个整数对应会第 i 项技能的人数。

输出格式:

输出至少有多少人 m 项都会。

输入样例:

50 4
30 35 42 46

输出样例:

3

测试点1就是人很多,会技能的人很少的时候 

测试点2就是人人都会m种技能

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n,m,num,sum=0;
    cin>>n>>m;
    for(int i=0;i<m;++i){
        cin>>num;
        sum+=num;
    }
    if(sum==n*m) cout<<n;    //n个人m个技能全都会,人人都会m种技能
                             //所以应该输出n
    else if (n>sum) cout<<"0";  //人很多,会技能的人很少的时候
    else cout<<sum-sum/n*n;     //普通情况
    return 0;
}

 L1-101 别再来这么多猫娘了!

 这题看起来很难,实际上一点也不简单,换句话说,我不会emmmm

L1-102 兰州牛肉面

分数 15

作者 陈越

单位 浙江大学

lamian.png

兰州牛肉面是历史悠久的美食,根据牛肉面的宽窄、配料的种类,可以细分为上百个不同的品种。你进到兰州的任何一家牛肉面馆,只说:“来一碗牛肉面!”就好像进到加州的咖啡馆说“来一杯咖啡”一样,会被店主人当成外星人……
本题的任务是,请你写程序帮助一家牛肉面馆的老板统计一下,他们一天卖出各种品种的牛肉面有多少碗,营业额一共有多少。

输入格式:

输入第一行给出一个正整数 N(≤100),为牛肉面的种类数量。这里为了简单起见,我们把不同种类的牛肉面从 1 到 N 编号,以后就用编号代替牛肉面品种的名称。第二行给出 N 个价格,第 i 个价格对应第 i 种牛肉面一碗的单价。这里的价格是 [0.01, 200.00] 区间内的实数,以元为单位,精确到分。
随后是一天内客人买面的记录,每条记录占一行,格式为:

品种编号 碗数

其中碗数保证是正整数。当对应的 品种编号 为 0 时,表示输入结束。这个记录不算在内。

输出格式:

首先输出 N 行,第 i 行输出第 i 种牛肉面卖出了多少碗。最后一行输出当天的总营业额,仍然是以元为单位,精确到分。题目保证总营业额不超过 106。

输入样例:

5
4.00 8.50 3.20 12.00 14.10
3 5
5 2
1 1
2 3
2 2
1 9
0 0

输出样例:

10
5
5
0
2
126.70
#include<bits/stdc++.h>
using namespace std;
int main(){
    int n,sum[101]={0};  //sum存储多少碗
    double money[101],moneysum=0;   //money存每碗的单价
    cin>>n;
    for(int i=1;i<=n;++i){
        cin>>money[i];            
    }
    int bianhao,wang;
    while(1){
        cin>>bianhao>>wang;       //输入编号和碗数
        if(!bianhao&&!wang) break;//输入都为0就结束循环
        sum[bianhao]+=wang;       //存储相应编号有多少碗
    }
    for(int i=1;i<=n;++i){
        cout<<sum[i]<<endl;       //输出每种编号有几碗
        moneysum+=sum[i]*money[i];    //总营业额+=碗数*单价
    }
    printf("%.2f",moneysum);    //保留两位小数
    return 0;
}

L1-103 整数的持续性

分数 20

作者 陈越

单位 浙江大学

从任一给定的正整数 n 出发,将其每一位数字相乘,记得到的乘积为 n1​。以此类推,令 ni+1​ 为 ni​ 的各位数字的乘积,直到最后得到一个个位数 nm​,则 m 就称为 n 的持续性。例如 679 的持续性就是 5,因为我们从 679 开始,得到 6×7×9=378,随后得到 3×7×8=168、1×6×8=48、4×8=32,最后得到 3×2=6,一共用了 5 步。
本题就请你编写程序,找出任一给定区间内持续性最长的整数。

输入格式:

输入在一行中给出两个正整数 a 和 b(1≤a≤b≤109 且 (b−a)<103),为给定区间的两个端点。

输出格式:

首先在第一行输出区间 [a,b] 内整数最长的持续性。随后在第二行中输出持续性最长的整数。如果这样的整数不唯一,则按照递增序输出,数字间以 1 个空格分隔,行首尾不得有多余空格。

输入样例:

500 700

输出样例:

5
679 688 697

 测试点2就是给你的数本来就是一位数,就不用变了

#include<bits/stdc++.h>
using namespace std;
int main(){
    int left,right,num,sum,max=0,count;
    vector<int>a;  //存储相同步数的数
    cin>>left>>right;        //输入左区间和右区间
    for(int i=left;i<=right;++i){    //遍历
    count=0;      //用于计数(既步数)
    num=i;        
    do{
        sum=1;
        while(num>0){
        sum*=num%10;    //计算每位数相乘后的值
        num/=10;        
        }
        ++count;        //每次乘完步数加一
        num=sum;
      }while(sum>9);
        if(i<9) count=0;    //如果一开始就是一位数就不用变了
        if(count>max){    //发现步数更多的
            max=count;
            a.clear();    //把之前存储的数全删掉
            a.push_back(i);  //加入步数更大的数i
        }
        else if(count==max){    //发现步数一样的
            a.push_back(i);     //把步数一样的存进去        
        }
    }
        cout<<max<<endl;    //输出最多的步数
        for(int i=0;i<a.size();++i){
            if(i) cout<<" ";        //行末尾不能有多余空格
            cout<<a[i];             //输出步数都是最多的数字
        }
    return 0;
}

L1-104 九宫格

分数 20

作者 陈越

单位 浙江大学

htls.jpg

九宫格是一款数字游戏,传说起源于河图洛书,现代数学中称之为三阶幻方。游戏规则是:将一个 9×9 的正方形区域划分为 9 个 3×3 的正方形宫位,要求 1 到 9 这九个数字中的每个数字在每一行、每一列、每个宫位中都只能出现一次。
本题并不要求你写程序解决这个问题,只是对每个填好数字的九宫格,判断其是否满足游戏规则的要求。

输入格式:

输入首先在第一行给出一个正整数 n(≤10),随后给出 n 个填好数字的九宫格。每个九宫格分 9 行给出,每行给出 9 个数字,其间以空格分隔。

输出格式:

对每个给定的九宫格,判断其中的数字是否满足游戏规则的要求。满足则在一行中输出 1,否则输出 0。

输入样例:

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

输出样例:

1
0
0

测试点0和2是看大正方形符不符合要求

测试点1是看你小正方形符不符合要求

测试点3是看你有没有考虑数字重复出现

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n,yes,sum,a[10][10],lie;
    cin>>n;
    while(n--){
        yes=1;        //yes是1结果就输出1,否则输出0
        int num[10]={0};    //检查数字会不会重复
        //输入部分
        for(int i=0;i<9;++i){
            for(int t=0;t<9;++t){
                cin>>a[i][t];
                if(a[i][t]>9||a[i][t]<1) yes=0;    //如果输入不是1~9,就不符要求
                else ++num[a[i][t]];    //存储符合要求的数字出现的次数
            }
        }
        
        //检查数字会不会重复
        for(int i=1;i<=9;++i)
        if(num[i]!=9)  {yes=0;break;}
        
        //数字不重复进行下一步检查
        if(yes){
        //考试题目理解错了啊啊啊,以为只要大正方形符合要求就行
        //没想到小正方形也要考虑,当场9分就没了555
        //检查每一个3*3小正方形是否符合要求
            for(int lie=0;lie<9&&yes==1;lie+=3){  //9个正方形从左到右检查
            for(int hang=0;hang<9;hang+=3){  //9正方形从上到下检查
                sum=0;
            for(int i=0;i<3;++i){    //对于一个小正方形从上到下
                for(int t=0;t<3;++t){  //接着从左到右相加
                    sum+=a[i+hang][t+lie];
                }
            }
            if(sum!=45){yes=0; break;}    //符合要求的话小正方形和一定是45
        }
        }
        }
        //数字不重复,小正方形符合要求,来看整个正方形
        if(yes){

             //从上到下判断大正方形每行符不符合要求
        for(int i=0;i<9;++i){   
            sum=0;
        for(int t=0;t<9;++t){
            sum+=a[i][t];
            }
        if(sum!=45) {yes=0;break;}  //每行和一定是45
        }

                //从左到右判断每列符不符合要求
        for(int i=0;i<9&&yes==1;++i){
            sum=0;
        for(int t=0;t<9;++t){
            sum+=a[t][i];
            }
        if(sum!=45) {yes=0;break;}  //同理,每列和一定是45
            }
            
        }

        //输出
        if(yes) cout<<"1\n";
        else cout<<"0\n";
    }
    return 0;
}

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值