成都neusoftACM2018上新生月赛(二)题解

这篇博客详细介绍了2018年成都neusoftACM新生月赛的多道算法题目,包括运动会中的BigInteger计算、攀岩安全分析、跳远比赛算法设计等。通过示例输入输出,解析了每道题目的解题思路和关键点,并提供了C语言的解题代码示例。
摘要由CSDN通过智能技术生成

Problem A: 运动会之——BigInteger

Time Limit: 1 Sec   Memory Limit: 256 MB
Submit: 168   Solved: 30
[ Submit][ Status][ Web Board] [ Edit] [ TestData]

Description

终于经过不懈努力,毛毛雨已经在我们oj上开通了java语言的提交选项!对很多人来说这是个值得高兴的事情。(我的大数终于可以不再用c来写这么长了23333

Biginteger是java里对大数的定义,可以计算很大很大的数字。然而鱼唇的我仍然不会写java TQT。

本题题意很简单,给你一个n,然后让你求2n的位数和值等于多少?

Input

测试数据有多组

对于每组测试数据输入一个正整数n ( n <= 10000)

Output

对于每组测试数据输出2n的位数和值。

Sample Input

3
5

Sample Output

1 8
2 32


c语言的大数加法基础。通过用数组来进行模拟实现,每一位数组存一位数字。比如1024,用数组来存就是4|2|0|1。至于2^10000次方有多少位数可以用math.h函数里面的log10(2^10000)来进行计算,就等于10000*log10(2)。可算出是3011位,所以数组开3100位足矣。接着直接暴力模拟数组即可。

学会使用后可以练习这道题http://acm.ccniit.com/old/problem.php?id=1257

#include<stdio.h>

#include<math.h>

#include<string.h>

int main()

{

    int a[3100],n,i,j;

    double num;

    while(~scanf("%d",&n))

    {

        num = ceil(n*log10(2));

        printf("%.0f ",num);

        memset(a,0,sizeof(a));

        a[1] = 1;

        for(i=1;i<=n;i++)

        {

            double num1 = ceil(i*log10(2));// 表示当前2^i次方的位数。

            int cnt = 0;//表示是否有进位。

            for(j=1;j<=num1;j++) // 如果这里循环到num的话会浪费多余的时间。

            {

                a[j] = a[j]*2 + cnt;

                if(a[j] >= 10)

                {

                    cnt = 1;

                    a[j] -= 10;

                }

                else cnt = 0;

            }

        }

        for(int i=num;i>=1;i--)

            printf("%d",a[i]);

        puts("");

    }

    return 0;

}



Problem B: 运动会之——攀岩

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 98   Solved: 22
[ Submit][ Status][ Web Board] [ Edit] [ TestData]

Description

攀岩运动有“壁上芭蕾”,“峭壁上的艺术体操”等美称,攀岩由登山运动衍生而来,富有很强的技巧性,冒险性,是极限运动中的一个重要项目。在世界上十分流行。

我们学校操场上也有个攀岩的道具。(然而只是一个摆设而已233333...)

假设)我们学校运动会有攀岩这项运动,大家都踊跃报名参加,当然热爱健身的大龙也参加了。由于攀岩是一个极限运动,所以大龙在攀岩的中途从高度为H的地方掉了下来。机智的大龙提前想到了他会掉下来,他提前就系好了安全绳,安全绳的长度为L米,绳的劲度系数为K。但是大龙太紧张了,在选择安全绳的时候没注意,就随便拿了一根安全绳。

现在问题来了:大龙掉下来会怎么样呢?

1:in the air.(在空中):大龙从始至终没掉在地上。

2:survives.(安全):大龙掉在地上的速度不超过10m/s。

3:death.(死亡):大龙掉在地上的速度超过10m/s。

Input

测试数据有多组。

对于每组测试数据输入四个实数安全绳的劲度系数K(牛顿/米),安全绳的长度L(米),大龙掉下来时的高度H(米),大龙的体重M(kg)

当输入数据都为0的时候结束。

重力加速度 g = 9.81(米/平方秒)

Output

对于每组测试数据输出大龙掉下来的结果。

Sample Input

350 20 30 75
375 20 30 75
450 20 30 75
0 0 0 0

Sample Output

death.
survives.
in the air.


一个高中物理题。重力势能F = m*h*g, 弹性势能F = (k*x^2)/2, 动能 W = (m*v^2)/2.

分为两种情况讨论。一种是(L < H) :说明大龙有可能在空中,但是现在需要计算绳子最大能伸长的距离x(m*g*h = k*x^2)/2),然后比较。如果(x < H-L)说明在空中,反之说明能够到达地面。然后通过(动能 = 重力势能 - 弹性势能)计算到达地面时的速度。如果速度大于10则death,反之survives。另一种是(L >= H),说明一定是到达地面的。继续通过通过(动能 = 重力势能 - 弹性势能)计算到达地面时的速度。如果速度大于10则death,反之survives。

#include<stdio.h>

#include<math.h>

int main()

{

    double k,v,l,s,w,g = 9.81;

    int flag;

    while(~scanf("%lf%lf%lf%lf",&k,&l,&s,&w))

    {

        if(!k and !l and !s and !w) break;

        if(l >= s)

        {

            v = sqrt(2*g*s);

            if(v <= 10) flag = 0;

            else flag = 2;

        }

        else

        {

            v = 2*g*s - k*(s-l)*(s-l)/w;

            if(v < 0) flag = 1;

            else if(v <= 100) flag = 0;

            else flag = 2;

        }

        if(!flag) printf("survives.\n");

        else if(flag == 1) printf("in the air.\n");

        else printf("death.\n");

    }

    return 0;

}


Problem C: 运动会之——跳远(上)

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 317   Solved: 81
[ Submit][ Status][ Web Board] [ Edit] [ TestData]

Description

跳远,又名急性跳远,田径运动跳跃项目。由助跑,起跳,腾空和落地等动作组合而成。运动员沿直线助跑,在起跳前沿线后用单足起跳,经腾空阶段,然后用双足在沙坑落下,比赛时以跳的远度决定名次。

顾名思义,跳远肯定是以跳的远度来决定名次。上周我校的运动会上也举行了跳远这项运动。但是由于参赛者没接触过跳远或者可能出现失误,所以每个参赛者有3次跳的机会,最终取每个人的最好成绩进行排名。

但是每次记分员用笔和纸来计算太慢了,所以让你设计一个算法算出前三名运动员的成绩。

Input

输入参赛运动员人数n(3 <=  n <= 1000)

接着n行,每行三个实数,表示每个运动员跳的距离。

Output

输出前三名运动员的成绩。保留两位小数

Sample Input

3
2.80 3.57 3.80
3.45 3.50 3.56
1.82 2.12 2.33

Sample Output

No.1: 3.80
No.2: 3.56
No.3: 2.33
本次的签到题,数据很小,冒泡排序或者选择排序均能通过。(注意读题)。代码略。


Problem D: 运动会之——跳远(下)

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 108   Solved: 13
[ Submit][ Status][ Web Board] [ Edit] [ TestData]

Description

跳远,又名急性跳远,田径运动跳跃项目。由助跑,起跳,腾空和落地等动作组合而成。运动员沿直线助跑,在起跳前沿线后用单足起跳,经腾空阶段,然后用双足在沙坑落下,比赛时以跳的远度决定名次。

在上周我校的运动会上举行了跳远这项运动。但是由于参赛者没接触过跳远或者可能出现失误,所以每个参赛者有3次起跳的机会,最终取每个人的最好成绩进行排名。

记分员现在愈发觉得我们ACMer是无所不能的,竟然已经开始嫌弃上次我们设计的算法。现在记分员要统计的人更多,并且还需要把每个人的排名,成绩,名字排列出来。所以这个记分员又来求助我们了。

Input

输入一个整数n,表示一共有n个参赛运动员。(3 <= n <= 100000)

接着输入n行,每行先输入一个字符串s表示参赛者的名字(1 <= strlen(s) <= 15)接着输入三个实数,表示参赛运动员3次起跳的成绩。

Output

输出n行。按照成绩-名字的顺序进行排列,如成绩相同则按照名字的字典序进行排序,保留五位小数。

注意:如果成绩相同则排名相同。

Sample Input

3
xiaoling 2.80000 3.57000 3.80000
xiaohong 3.45000 3.50000 3.56000
xiaoming 1.82000 2.12000 2.33000

Sample Output

No.1 is xiaoling: 3.80000
No.2 is xiaohong: 3.56000
No.3 is xiaoming: 2.33000

结构体快排,如成绩相同则按照名字字典序进行排序,且成绩相同时排名相同。排序涉及到c++里stl库函数的sort,字典序可通过strcmp函数的返回值解决。

#include<string.h>

#include<iostream>

#include<algorithm>

using namespace std;

struct node{

    char s[50];

    double num;

}a[100010];

int cmp(node a,node b)

{

    if(a.num == b.num)

    {

        if(strcmp(a.s,b.s) > 0) return 0;

        else return 1;

    }

    return a.num > b.num;

}

int main()

{

    int n;scanf("%d",&n);

    for(int i=0;i<n;i++)

    {

        scanf("%s",a[i].s);

        for(int j=0;j<3;j++)

        {

            double x;

            scanf("%lf",&x);

            a[i].num = max(a[i].num,x);

        }

    }

    sort(a,a+n,cmp);

    int tmp = 1;

    for(int i=0;i<n;i++)

    {

        if(i and a[i].num != a[i-1].num) tmp = i+1;

        printf("No.%d is %s: %.5f\n",tmp,a[i].s,a[i].num);

    }

    return 0;

}

Problem E: 运动会之——引体向上

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 103   Solved: 21
[ Submit][ Status][ Web Board] [ Edit] [ TestData]

Description

引体向上,是体育课程中会考的项目之一。为男生上肢力量的考察项目,是自身力量克服自身重力的悬垂力量练习。是最基本的锻炼背部的方法,也是衡量男生体质的重要标准之一。

大龙也想参加这项运动,可惜emmmmmmm.......哎。。。(活着挺好的。

现在有n个人报名参加引体向上这个项目,大家都抱着必胜的心态参加!但是预言家学chang已经预知到了第k个人最终会获得第一名。因为厉害的人会有膨胀的心态,所以当前做的最多的那一个人就会在单杠上等剩下的人做一个。现在问第k个人要获得第一名的话需要再做多少个?(第k个人不会膨胀)

该运动的规则是这样的:从上单杠的时候开始,不计时,只记数。按最后坚持不住的时候的个数为自己的最终成绩。

Input

第一行输入一个n(2 <= n <= 100000)表示有n个参加运动员,再输入一个k表示最终第k个人会获胜。

接着输入n个数,表示经过一段时间(忽略不计)每个人完成引体向上的个数a[i](0 <= a[i] <= 10000)

Output

输出第k个人获得第一名需要再做多少个引体向上

Sample Input

5 3
1 1 3 4 4

Sample Output

4

HINT

第一次。第4个人膨胀,所以变成了2 2 4 4 5


第二次。第5个人膨胀,所以变成了3 3 5 5 5


第三次。第4个人膨胀,所以变成了4 4 6 5 6


第四次。第5个人膨胀,所以变成了5 5 7 6 6   第三个人获胜。

思维题。拿样例来说。1 1 3 4 4,我要使得第3个人最后的值最大。所以比3小的两个1可以忽略。到第一个4的时候,题目说明的处理方式为当前数不变,别的数均+1。换句话说就是当前数-1,别的数均不变。所以要把4变成比3小的数需要执行两步,第二个4亦然。故答案为4。一层循环便利即可。

#include<stdio.h>

int main()

{

    int n,k,a[100010];

    scanf("%d%d",&n,&k);

    for(int i=1; i<=n; i++) scanf("%d",&a[i]);

    int sum = 0;

    for(int i=1;i<=n;i++)

        if(i!=k and a[i]>=a[k]) sum += 1+a[i]-a[k];

    printf("%d\n",sum);

    return 0;

}


Problem F: 运动会之——乒乓球

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 285   Solved: 72
[ Submit][ Status][ Web Board] [ Edit] [ TestData]

Description

乒乓球,中国国球,是一种世界流行的球类体育项目。包括进攻防守,对抗和防守等各种方式。发球,切球,扣球,旋球等各种技巧。是一场体力与智力的竞争。

现在有n名同学报名参赛运动会乒乓球这个项目。但是由于人数众多,所以比赛执行两两对抗的方法。一场比赛中胜者胜出,晋级下一轮,输者淘汰,直接出局。爱打球且厉害的学chang自然也报名参赛了。学chang想知道如果他想获得第一的话至少得打多少场比赛呢?

(学chang欢迎挑战(手动滑稽)(逃。

Input

测试数据有多组,对于每组测试数据输入一个n(1 <= n <= 2^31)

当n=0时结束。

Output

输出学chang如果要获得第一名需要至少打多少场比赛呢?

Sample Input

2
0

Sample Output

1

#include<stdio.h>

#include<math.h>

int main()

{

    long long n;

    while(~scanf("%lld",&n),n)

        printf("%.0f\n",ceil(log2(n)));

    return 0;

}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值