• 『ACM C++』 PTA 天梯赛练习集L1 | 007-011


      真的是忙头晕了,学业、ACM打题、班级活动、自学新东西,哇这充实的大学~

    ------------------------------------------------L1-007----------------------------------------------------------

    念数字

    输入一个整数,输出每个数字对应的拼音。当整数为负数时,先输出fu字。十个数字对应的拼音如下:

    0: ling
    1: yi
    2: er
    3: san
    4: si
    5: wu
    6: liu
    7: qi
    8: ba
    9: jiu
    

    输入格式:

    输入在一行中给出一个整数,如:1234

    提示:整数包括负数、零和正数。

    输出格式:

    在一行中输出这个整数对应的拼音,每个数字的拼音之间用空格分开,行末没有最后的空格。如 yi er san si

    输入样例:

    -600

    输出样例:

    fu liu ling ling

    ------------------------------------------------L1-007----------------------------------------------------------

    注:水题,熟练使用字符指针数组就没有问题了。如这里的:const char* proun[10] = { "ling", "yi", "er", "san","si","wu","liu","qi","ba","jiu" };

    #include<stdio.h>
    #include<string.h>
    #include<string>
    using namespace std;
    const char* proun[10] = { "ling", "yi", "er", "san","si","wu","liu","qi","ba","jiu" };
    char Input[999999];
    int length;
    int main()
    {
        scanf("%s",&Input);
        length = strlen(Input);
        for(int i = 0;i<length;i++)
        {
            if(Input[i] == '-') printf("fu");
            else printf(proun[Input[i] - '0']);
            if(i!=length-1) printf(" ");
            else printf("
    ");
        }
        return 0;
    }

    ------------------------------------------------L1-008----------------------------------------------------------

    求整数段和

    给定两个整数A和B,输出从A到B的所有整数以及这些数的和。

    输入格式:

    输入在一行中给出2个整数A和B,其中100AB100,其间以空格分隔。

    输出格式:

    首先顺序输出从A到B的所有整数,每5个数字占一行,每个数字占5个字符宽度,向右对齐。最后在一行中按Sum = X的格式输出全部数字的和X

    输入样例:

    -3 8

    输出样例:

       -3   -2   -1    0    1
        2    3    4    5    6
        7    8
    Sum = 30

    ------------------------------------------------L1-008----------------------------------------------------------

    注解:水题,一个循环带过

    #include<stdio.h>
    
    int A,B,counter,sum;
    int main()
    {
        scanf("%d%d",&A,&B);
        counter = sum = 0;
        for(int i = A;i<=B;i++)
        {
            sum+=i;
            if(counter == 5)
            {
                counter = 0;
                printf("
    ");
            }
            printf("%5d",i);
            counter++;
        }
        printf("
    Sum = %d
    ",sum);
        return 0;
    }

    ------------------------------------------------L1-009----------------------------------------------------------

    N个数求和

    本题的要求很简单,就是求N个数字的和。麻烦的是,这些数字是以有理数分子/分母的形式给出的,你输出的和也必须是有理数的形式。

    输入格式:

    输入第一行给出一个正整数N≤100)。随后一行按格式a1/b1 a2/b2 ...给出N个有理数。题目保证所有分子和分母都在长整型范围内。另外,负数的符号一定出现在分子前面。

    输出格式:

    输出上述数字和的最简形式 —— 即将结果写成整数部分 分数部分,其中分数部分写成分子/分母,要求分子小于分母,且它们没有公因子。如果结果的整数部分为0,则只输出分数部分。

    输入样例1:

    5
    2/5 4/15 1/30 -2/60 8/3

    输出样例1:

    3 1/3

    输入样例2:

    2
    4/3 2/3

    输出样例2:

     2

    输入样例3:

    3
    1/3 -1/6 1/8

    输出样例3:

    7/24

    ------------------------------------------------L1-009----------------------------------------------------------

    注解:这题我居然WA了好一会,出现了两个问题,一个是叠乘超出long long int的问题,一个就是出现了/0的情况。下面进行分析:

    · 代码分块:

      第一步:先套用获取最小公倍数的模板:

    long long gcd(long long m, long long n)
    {
        return (m==0)?n:gcd(n%m, m);
    }
    long long lcm(long long a, long long b)
    {
       return a / gcd(a, b) * b;
    }

      第二步:得到化简功能函数!!

    void hj(long long int &a,long long int &b)
    { 
        long long int m,n,p;
        m=a;n=b;p=m%n;
        while(p!=0)
        {
            m=n;n=p;
            p=m%n;
        }
        if(n!=0) //化为最简分式
        {
            a/=n;
            b/=n;
        }
        if(b<0) //处理分母为复数
        {
            a=-a;
            b=-b;
        }
    }

      第三步:输入的同时进行通分、加和,最重要的是一定要记得时刻化简!!原本有一个test3测试点疯狂的出错,我看到了不超过长整形,所以用了long long int,但是突然想到,如何是加和乘积,是极有可能爆long long int的,所以要时刻进行化简,就过了。

        for(int i = 1;i<times;i++)
        {
            scanf("%lld/%lld",&temp_up,&temp_down);
            long long int temp = lcm(temp_sumdown,temp_down);
            if(temp_sumdown<temp) temp_sumup*=(temp/temp_sumdown);
            if(temp_down<temp) temp_up*=(temp/temp_down);
            temp_sumdown = temp;
            temp_sumup+=temp_up;
            hj(temp_sumup,temp_sumdown);
        }

      第四步:分子包含了符号,也就说,对于分子为正的数,进行整数化处理:

        for(int i = 1;i<times;i++)
        {
            scanf("%lld/%lld",&temp_up,&temp_down);
            long long int temp = lcm(temp_sumdown,temp_down);
            if(temp_sumdown<temp) temp_sumup*=(temp/temp_sumdown);
            if(temp_down<temp) temp_up*=(temp/temp_down);
            temp_sumdown = temp;
            temp_sumup+=temp_up;
            hj(temp_sumup,temp_sumdown);
        }

      第五步:对输入0进行单独处理,这里是我之前没想到的事情,一直test5出错,加了下面这句话之后就过了。

    else if(temp_sumup == 0) printf("0
    ");

      第六步:对分子为负数的情况进行符号处理:

        else
        {
            temp_sumup*=-1;
            long long int intt = temp_sumup/temp_sumdown;
            long long int up = temp_sumup - intt*temp_sumdown;
            long long int down = temp_sumdown; 
            hj(up,down);
            if(intt>0)
            {
                printf("-%lld",intt);
                if(up>0) printf(" -%lld/%lld
    ",up,down);
                else printf("
    ");
            }
            else printf("-%lld/%lld
    ",temp_sumup,temp_sumdown);
        }

     

    · AC代码:

    #include<stdio.h>
    #include<math.h>
    using namespace std;
    long long int times,temp_up,temp_down;
    long long int temp_sumup,temp_sumdown;
    void hj(long long int &a,long long int &b)
    { 
        long long int m,n,p;
        m=a;n=b;p=m%n;
        while(p!=0)
        {
            m=n;n=p;
            p=m%n;
        }
        if(n!=0) //化为最简分式
        {
            a/=n;
            b/=n;
        }
        if(b<0) //处理分母为复数
        {
            a=-a;
            b=-b;
        }
    }
    long long gcd(long long m, long long n)
    {
        return (m==0)?n:gcd(n%m, m);
    }
    long long lcm(long long a, long long b)
    {
       return a / gcd(a, b) * b;
    }
    int main()
    {
        scanf("%lld",&times);
        scanf("%lld/%lld",&temp_sumup,&temp_sumdown);
        for(int i = 1;i<times;i++)
        {
            scanf("%lld/%lld",&temp_up,&temp_down);
            long long int temp = lcm(temp_sumdown,temp_down);
            if(temp_sumdown<temp) temp_sumup*=(temp/temp_sumdown);
            if(temp_down<temp) temp_up*=(temp/temp_down);
            temp_sumdown = temp;
            temp_sumup+=temp_up;
            hj(temp_sumup,temp_sumdown);
        }
        if(temp_sumup >0)
        {
            long long int intt = temp_sumup/temp_sumdown;
            long long int up = temp_sumup - intt*temp_sumdown;
            long long int down = temp_sumdown; 
            hj(up,down);
            if(intt>0)
            {
                printf("%lld",intt);
                if(up>0) printf(" %lld/%lld
    ",up,down);
                else printf("
    ");
            }
            else printf("%lld/%lld
    ",temp_sumup,temp_sumdown);
        }
        else if(temp_sumup == 0) printf("0
    ");
        else
        {
            temp_sumup*=-1;
            long long int intt = temp_sumup/temp_sumdown;
            long long int up = temp_sumup - intt*temp_sumdown;
            long long int down = temp_sumdown; 
            hj(up,down);
            if(intt>0)
            {
                printf("-%lld",intt);
                if(up>0) printf(" -%lld/%lld
    ",up,down);
                else printf("
    ");
            }
            else printf("-%lld/%lld
    ",temp_sumup,temp_sumdown);
        }
    
        return 0;
    }

     

    ·AC截图:

    · 解后反思:

      这里提到了三个模板需要熟记于心,一个是化简模板、一个是gcd、还有一个lcm模板,可能之后要经常用到~然后就是要时刻注意加减乘除四种运算是否会爆long long int的情况,以及对特殊情况的处理

    ------------------------------------------------L1-010----------------------------------------------------------

    比较大小

    本题要求将输入的任意3个整数从小到大输出。

    输入格式:

    输入在一行中给出3个整数,其间以空格分隔。

    输出格式:

    在一行中将3个整数从小到大输出,其间以“->”相连。

    输入样例:

    4 2 8

    输出样例:

    2->4->8

    ------------------------------------------------L1-010----------------------------------------------------------

    注解:水题,一个sort即可解。

    #include<stdio.h>
    #include<algorithm>
    using namespace std;
    int temp[3];
    int main()
    {
        scanf("%d %d %d",&temp[0],&temp[1],&temp[2]);
        sort(temp,temp+3);
        printf("%d->%d->%d
    ",temp[0],temp[1],temp[2]);
        return 0;
    }

    ------------------------------------------------L1-011----------------------------------------------------------

    A-B 

    本题要求你计算AB。不过麻烦的是,A和B都是字符串 —— 即从字符串A中把字符串B所包含的字符全删掉,剩下的字符组成的就是字符串AB。

    输入格式:

    输入在2行中先后给出字符串A和B。两字符串的长度都不超过104​​,并且保证每个字符串都是由可见的ASCII码和空白字符组成,最后以换行符结束。

    输出格式:

    在一行中打印出AB的结果字符串。

    输入样例:

    I love GPLT!  It's a fun game!
    aeiou

    输出样例:

    I lv GPLT!  It's  fn gm!

    ------------------------------------------------L1-011----------------------------------------------------------

    注解:这道题我WA了好一会,总感觉思路很正确没毛病,结果出错在输入的函数选择上:

    #include<iostream>
    #include<cstring>
    using namespace std;
    string a,b;
    bool vis[10005];
    int main()
    {
        getline(cin,a);
        getline(cin,b);
        for(int i=0;i<b.length();i++) vis[b[i]+5000]=1;
        for(int i=0;i<a.length();i++) if(vis[a[i]+5000] == 0) cout<<a[i];
        cout<<endl;
        return 0;
    }

    疑问:使用cin.getline对char数组输入是会WA的,至今不知道为什么,而使用getline(cin,string)对string类输入却能直接AC,希望有大神能够留言帮我解决这个问题~ 万分感谢。同时耶告诉我以后再这方面需要注意,对于空格和换行符的输入的时候,多使用几种输入方法,可能就能通过AC了~

    注:如果有更好的解法,真心希望您能够评论留言贴上您的代码呢~互相帮助互相鼓励才能成长鸭~~

  • 相关阅读:
    CAST和CONVERT
    #pragma 预处理指令详解
    Android系统移植主要事项
    Java动态绑定机制的内幕
    Java接口和抽象类用法总结
    Android工程的编译过程
    点击按钮,并且实现增加一个按钮的效果 (附效果图)
    iOS-设置导航栏"返回"按钮 (附效果图)
    常用代码整理(重要)
    NSTimer 的暂停与恢复运行。
  • 原文地址:https://www.cnblogs.com/winniy/p/10486995.html
Copyright © 2020-2023  润新知