2022/11/27练习赛解析

7-1 四则运算

输入一个形式如“操作数运算符操作数”的四则运算表达式(运算符可以是 + - / 也可是其它符号), + - * /输出运算结果。其它符号输出“Unknown operator”,如果运算符是“/”,结果保留两位小数,若运算符是“/”且第二个操作数为0,则输出“Invalid Value!”

输入格式:

输入格式为a运算符b,注意a,b均为整数,且0<=a,b<=100000000

输出格式:

=运算结果

输入样例:

在这里给出一组输入。例如:
3/2

输出样例:

在这里给出相应的输出。例如:
=1.50

输入样例:

在这里给出一组输入。例如:
3_2

输出样例:

在这里给出相应的输出。例如:
Unknown operator

本题进行了简单的模仿计算器的功能。
仅需要按照格式读取并且判断正误加上是什么运算符然后输出即可。

#include <stdio.h>
int main(void)
{
    long long a,b;
    char c;
    scanf("%lld%c%lld",&a,&c,&b);
    if(c=='+')
        printf("=%lld",a+b);
    else if(c=='-')
        printf("=%lld",a-b);
    else if(c=='*')
        printf("=%lld",a*b);
    else if(c=='/')
    {
        if(b!=0)//判断分母非0
            printf("=%.2f",(double)a/b);
        else
            printf("Invalid Value!");
    }
    else
        printf("Unknown operator");
    return 0;
}

7-2 A+B(III)

计算 a+b 并以标准格式输出总和----也就是说,从最低位开始每隔三位数加进一个逗号(千位分隔符),如果结果少于四位则不需添加。

输入格式:

共一行,包含两个整数 a 和 b,−106≤a,b≤106

输出格式:

共一行,以标准格式输出 a+b 的和。

输入样例:

在这里给出一组输入。例如:
-1000000 9

输出样例:

在这里给出相应的输出。例如:
-999,991

首先这个数大小并不是很大,不放心可以用long去接收。
然后难点在于输出a+b的和的格式问题。题目要求从最低为开始每隔三位数加一个逗号。
可以把答案拆解然后在依次打印中加入打印逗号即可。

#include <stdio.h>
#include <math.h>
int main(void)
{
    long a,b;
    scanf("%ld %ld",&a,&b);
    long c=a+b;
    if(c==0)//等于0特殊情况直接处理
    {
        printf("0");
        return 0;
    }
    if(c<0)//负数改正数
    {
        printf("-");
        c = -c;
    }
    long c_t=c;
    int count=0;
    for(int i=10;c_t>0;)
    {
        c_t /= i;
        count++;
    }//算出答案的位数
    int wei[count];
    int wei_i=0;
    for(int i=pow(10,count-1);i>0;i/=10)
    {
        wei[wei_i++]=c/i;//将答案按位依次拆解进数组内
        c%=i;
    }
    for(int i=0;i<count;i++)
    {
        if((count-i)%3==0&&i!=0)//每三位打印一个逗号,除去特殊情况
            printf(",");
        printf("%d",wei[i]);
    }
    return 0;
}

7-3 耗电量

小烤是一名专业的oier!

最近闲来无事,他对自己最喜欢的笔记本电脑的耗电量感兴趣了起来。

他的笔记本电脑有三种模式。在正常模式下,笔记本电脑每分钟耗电功率P1。在小烤最后一次使用电脑经过T1分钟后,屏幕保护程序自动启动,功耗变为P2。而在屏幕保护程序启动T2分钟后,笔记本电脑切换到“睡眠”模式,功耗为P3。

已知小烤使用笔记本电脑的时间可以分为n个时间段[l1, r1], [l2, r2], …, [ln, rn]。在每个时间段内,保证小烤一直在使用笔记本电脑。在结束一个时间段后,小烤立刻停止使用,直到下一个时间段来临。

请帮助小烤计算从第一次开始使用时间l1到最后一次使用完rn之间总共耗电量是多少?

输入格式:

第一行包含6个整数n,P1,P2,P3,t1,t2(1 ≤ n ≤ 100, 0 ≤ p1,p2,p3 ≤ 100, 1 ≤t1,t2  ≤60)。

接下来n行为小烤使用笔记本电脑的时间段描述:l i和r i(保证数据正确,且总耗电量不超过int范围)。

输出格式:

输出总共的耗电量

输入样例:

在这里给出一组输入。例如:
1 3 2 1 5 10
0 10

输出样例:

在这里给出相应的输出。例如:
30

题目较长,分析起来就是:
在小烤时间段内都是正常使用电脑(每分钟耗电功率P1),在结束一个时间段后就会开始计时,T1分钟后功耗变为P2,再过T2分钟后功耗变为P3。
例如[l1,r1],[l2,r2]。那么在l1到r1和l2到r2过程中电脑功耗P1,在r1到l2过程中,从r1开始到r1+T1分钟过程中功耗为P1,在r1+T1到r1+T1+T2过程中功耗为P2,在r1+T1+T2之后功耗一直为P3,直到下一次小烤时间段[l3,r3]。(这里假设r1+T1+T2<l3)
输入案例解析:只有一个时间段,所以P1*(r1-l1)就是答案,即3*(10-0)

#include <stdio.h>
int main(void)
{
    int n,p1,p2,p3,t1,t2;
    scanf("%d %d %d %d %d %d",&n,&p1,&p2,&p3,&t1,&t2);
    int sum=0;
    int l_last=-1,r_last=-1;
    while(n--)//n个时间段
    {
        int li,ri;int total=0;//total记录上个时间段(如果有)结束到这次时间段开始的总耗能
        scanf("%d %d",&li,&ri);
        if(r_last!=-1)//规避无上次时间段的情况(也就是第一个时间段)
        {
            int bao=li-r_last;
            if(bao<=t1)
                total=bao*p1;
            else if(bao<=t2+t1)
                total=t1*p1+(bao-t1)*p2;
            else
                total=t1*p1+t2*p2+(bao-t2-t1)*p3;
        }//类似于阶梯收费
            r_last=ri;//记录每次结束时间
        sum += p1 *(ri-li) + total;
    }
    printf("%d",sum);
    return 0;
}

7-4 小灯泡

小明面前有一排小灯泡共n个,每个灯泡由一个独立的开关控制,按一下开关则可以改变灯的状态(开->关 ,关->开),现在所有灯泡都是关着的,小明现在进行n轮游戏,第i轮游戏他会依次按下所有i的倍数的开关,问当小明完成游戏后有多少个小灯泡是亮的

输入格式:

输入在一行输入一个整数n(n<2^31)。

输出格式:

输出游戏结束后开着的小灯泡的数量

输入样例:

在这里给出一组输入。例如:
1

输出样例:

在这里给出相应的输出。例如:
1

输入样例:

在这里给出一组输入。例如:
2

输出样例:

在这里给出相应的输出。例如:
1

本题说第i轮游戏他会依次按下所有i的倍数的开关。
也就是意味着第i个灯泡只有是第(它的因数)才可以控制。
一开始全关,那么也就是说只有i的因数个数是奇数的最后才可以亮
原理:指数是偶数,那么偶数加1,得到的是一个奇数,而无论多少个奇数相乘,结果都是奇数。所以说完全平方数的因数个数是奇数个。

当然如果一个数的因数个数是奇数个,说明这个自然数这一定是个完全平方数。

#include <stdio.h>
int main(void)
{
    long long n;
    scanf("%lld",&n);
    int count=0;
    for(int i=1;i*i<=n;i++)//利用完全平方数的定义去循环可大大减少循环次数
    {
        count ++;
    }
    printf("%d",count);
    return 0;
}

7-5 买纸抽

小明去商店买纸抽,商店里有k种不同包装规格的纸抽,第i种包装规格的纸抽,恰好含有i包,现在小明要买n包纸抽,但是他只能购买一种规格的纸抽,他最少需要购买几包同种规格的纸抽,才能恰好买到n包纸抽(测试数据保证有解)

输入格式:

输入在一行中给出2个值不超过1000000000的正整数n和k。

输出格式:

输出一个整数表示最少的购买数量

输入样例:

在这里给出一组输入。例如:
8 7

输出样例:

在这里给出相应的输出。例如:
2

本题实际考察一个数的因数,最理想情况是k>=n,那么就只需要拿一包n种包装规格的纸抽就行,再往下就是判断能不能拿两包…三包…四包。
因为最小的因数1对应的是最大的因数n,根据归纳法或者数学原理可得,当超过根号n的时候就只有唯一因数n了。
亲测根号n换成n/2会运行超时

#include <stdio.h>
#include <math.h>
int main(void)
{
    long long n,k;
    scanf("%lld %lld",&n,&k);
    for(int i=1;i<=sqrt(n)+1;i++)//从最理想情况开始考虑
    {
        if(n%i==0&&n/i<=k)//判断能否整除和是否可以拿
        {
            printf("%d",i);
            return 0;
        }
    }
    printf("%d",n);//最坏情况
    return 0;
}

修正:sqrt(n) --> sqrt(n)+1
TIP:我记得我有一个代码是不用这样修改的,也可以正确解出 12 3

7-6 方程

小明最近在学解方程,小明今天遇到了一个特殊的方程ax+by=xy,小明想知道满足方程的正整数(x,y)有多少对。

输入格式:

输入在一行中给出2个不超过1000000的正整数A和B。

输出格式:

满足方程的正整数对(x,y)的数量

输入样例:

在这里给出一组输入。例如:
1 2

输出样例:

在这里给出相应的输出。例如:
2

本题方程需要化简:
化简一(失败):y=ax/(x-b)
本想循环遍历x的范围,让ax%(x-b)==0,结果x的范围和(a-1)难脱关系,好像也得不出正确答案
化简二(成功):(x-b)(y-a)=ab
题目就化为求ab的约数,利用约数个数定理可快速得答案。

解方程思路也可以百度参考x+y=xy的解法

#include <stdio.h>
int main(void)
{
    long long a,b;
    scanf("%lld %lld",&a,&b);
    long long di=2;
    long long zhi=0;
    long long ab=a*b;
    long long sum=1;
    while(ab>1)
    {
        if(ab%di==0)
        {
            ab /= di;
            zhi++;
        }
        else
        {
            di++;
            sum *= (zhi+1);
            zhi=0;
        }
    }sum *= (zhi+1);
    printf("%lld",sum);
    return 0;
}

偷分小技巧(代码)

#include <stdio.h>
int main(void)
{
    long a,b;
    scanf("%ld %ld",&a,&b);
    printf("%ld",b);
    return 0;
}

以上题目出题人:

作者 杨超
单位 广东东软学院

题目通用限制

代码长度限制

16 KB

时间限制

400 ms(最后一题为50ms)

内存限制

64 MB

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值