中国石油大学 2018-2019赛季多校联合新生训练赛第一场 题解与补题

这篇博客介绍了中国石油大学2018-2019赛季多校联合新生训练赛的第一场比赛,包括多个编程题目,如录取分数线、电子警察、查找特定合数等。博主分享了对每个问题的解题思路和常见陷阱,涉及到数据处理和算法应用。
摘要由CSDN通过智能技术生成

这场比赛是在18年12月,因为当时完全不敢用C++,感觉很遥远的样子…代码都是拿C实现的,许多地方其实也可以优化的。

问题 A: 录取分数线

时间限制: 1 Sec 内存限制: 128 MB
题目描述
新学年,学校将成立信息学兴趣小组提高班。由于指导教师精力有限,只能以选拔考试的成绩为依据,按从高到低的分数,从N个参加选拔的学生中录取不超过M个成员。录取的成员要尽可能地多,但不得超过M个(含M个)。由于可能会有并列分数出现,为了保证公平,有时只得忍痛割爱,可能录取的成员会达不到计划数M。请你编程划定录取分数线。

输入
有N+1行,第一行是报名人数N和录取人数M。以下N行是考试成绩,已按从高到低的顺序排列。N、M和成绩均是1000以内的正整数,N≥M。数据保证不会所有的成绩都相同。

输出
只有1行,为录取分数线。

样例输入
10 5
99
98
97
96
95
94
93
92
91
90

样例输出
95

题目分析
第一题送福利,只判断第m+1位是否与第m位相等即可。若不相等则为第m位成绩,相等则从m往回找找到第一个大于m+1位成绩的学生的成绩即可。

#include<stdio.h>
#define N 100000
int main(void)
{
   
    int a[N],n,m,i,j,t;
    scanf("%d %d",&n,&m);
    for(i=0;i<n;i++)
        scanf("%d",&a[i]);
    for(i=0;i<n;i++)//其实这段排序可以删掉我没注意题目中已经有序
        for(j=0;j<n-i;j++)
            if(a[j]<a[j+1])
            {
   
                t=a[j];
                a[j]=a[j+1];
                a[j+1]=t;
            }
    i=m-1;
    if(a[i]==a[m])
    {
   
        while(a[i]==a[m-1]) i--;
    }
    printf("%d",a[i]);
    return 0;
}

问题 B: 电子警察

时间限制: 1 Sec 内存限制: 128 MB
题目描述
现在很多地方的道路路口都安装了电子警察,即交通违章自动拍照系统。这些系统一般在路口的地下埋设感应线圈,通过传感器判断汽车是否在红灯时通过路面,来控制数码相机自动拍照。在安装这种系统需要挖掘地面,施工麻烦,成本又高。于是有人研究出了同摄像机自动识别车牌并判断违章行为的系统,这样一来,电子警察安装就方便多了,成本也大大降低。请你编程实现其中的一个功能,给出一批某一时间识别后的车牌号码及行进方向,判断该车是否违章,并记录下来。违章的规则设定为:先设置左转、直行、右转依次绿灯通行时间(以秒为单位,只允许一个方向绿灯),先左转绿灯,然后直行绿灯,最后右转绿灯,在其中一个绿灯时,其余两盏灯为红灯状态,假设时间生效在零时整,且给出的数据只限定当天。闯红灯为违章。

输入
第1行有4个整数,以一个空格隔开,依次为左转、直行、右转通行的绿灯持续秒数和识别的车辆数N(1≤N≤10000),后面的N行,表示每辆车的信息,格式为“时间+方向+车牌”,其中时间为6位数字,方向为1个字母(L表示左转,S表示直行,R表示右转),车牌为8个字符,之间没有空格。如081528LZJBB0001,表示车牌号为ZJBB0001的车辆在8时15分28秒左转。

输出
违章车辆的车牌号码,每辆车一行,不含空格,按输进去的先后顺序输出。

样例输入
15 30 20 3
000046SZJBB8888
030950LJSAA9999
201509RBJC7777D

样例输出
ZJBB8888
BJC7777D

题目分析
这道题我吃了10次罚时…主要还是细节问题,比如最后一秒取余以后会变为0,此时要把0当做右转处理,以及对于输入行末空格的处理等等…现在想想用cin或者scanf读入就没这回事了
判断条件解释:取余后左转的时间为(0,l],直行时间为(l,s],右转时间为(s,r)和0,只要转向与时间不符则为闯红灯。

#include<stdio.h>
#include<string.h>
#define N 20
int main(void)
{
   
    char a[N];
    int n,i,l,s,r,c,j,d;
    scanf("%d %d %d %d",&l,&s,&r,&n);
    while(getchar()!='\n');//处理行末空格,不加while会WA
    s=l+s;//s此时代表直行结束的时刻
    r=s+r;//r此时代表右转结束的时刻,即一个周期的时长
    while(n-->0)
    {
   
        gets(a);
        c=0;//c代表从计时开始共经历的时间长度对总时长取余后的结果
        for(j=0;j<3;j++)
        {
   
            d=0;
            for(i=j*2;i<j*2+2;i++)
                d=d*10+a[i]-'0';
            c=c*60+d;
            c=c%r;
        }
        if((a[6]=='L'&&(c==0||c>l))||(a[6]=='S'&&(c<=l||c>s))||(a[6]=='R'&&c<=s&&c!=0))
            puts(a+7);
    }
    return 0;
}

问题 C: 查找特定的合数

时间限制: 1 Sec 内存限制: 128 MB
题目描述
自然数中除了能被1和本身整除外,还能被其他数整除的数叫合数。每个合数都可以写成几个质数相乘的形式,这几个质数都叫做这个合数的质因数。比如8=2×2×2,2就是8的质因数。在1—N(N≤200000)按从小到大顺序排列的自然数序列中,查找第M个有X(2≤X≤6)个不同质因数的合数。例如,第3个有2个不同质因数的合数是12(12只有2、3两个不同的质因数,在12之前有2个不同质因数的合数分别为6和10)。

输入
共1行,分别为M,X。

输出
共1行,为第M个有X个不同质因数的合数。

样例输入
3 2

样例输出
12

解题思路
这道题思路很简单,从2开始进行枚举,对每一个数i,从2到i枚举j,如果j是i的因子则让i除以j,直到i没有j这个因子为止,并令计数器+1,如果i中含有的因子数量(计数器)和x相等就让m-1,当m减到0时就意味着当前枚举的数是第m个符合条件的数,于是就有了我最初的代码:

#include<stdio.h>
#include<stdlib.h>
int main(void)
{
   
    int m,x,i,k,j,c=0;
    scanf("%d %d",&m,&x);
    for(i=2;m>0&&i<200000;i++)
    {
   
        k=i;//防止因为循环内的计算改变i的值
        c=0;
        for(j=2;j*2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值