杭电OJ回归水题2012—2030、2032、2040、2042、2054、2055

从我开始刷杭电oj到现在已经差不多半个月了,这半个月主要是练习了C语言的题目,总共完成53题,排名31290名,经过50题左右的训练,现在已经较好的掌握了C语言习题的解法,接下来进入到算法相关的题目,12天完成31题。
2012

#include<stdio.h>
int main()
{
    int x,y,i,m,n,j;
    while(scanf("%d %d",&x,&y)!=EOF&&(x!=0||y!=0))
    {
        m=0;
        flag=0;
        for(i=x;i<=y;i++)
        {
            m=i*i+i+41;
            for(j=2;j<m;j++)   //从2开始遍历到m
               {
                    if(m%j==0)  //如果m%j等于0,说明m不是质数,将flag置为1
                    {
                        flag=1;
                           break;
                    }
               }
        }
           if(flag==0)
        printf("OK\n");
           else printf("Sorry\n");
    }
       return 0;
}

2013

#include<stdio.h>
int main()
{
    int n,sum;
    while(scanf("%d",&n)!=EOF)
    {
    sum=1;
    while(--n)
    {
        sum=(sum+1)*2;  //猴子将桃子吃掉一半多一个,那前一天的总和为(sum+1)*2
    }
    printf("%d\n",sum);
    }
    return 0;
}

2014

#include<stdio.h>
int main()
{
    int n,i;
    double min,max,a[100],sum,score;
    while(scanf("%d",&n)!=EOF)
    {
        min=99999,max=0,sum=0;
        for(i=0;i<n;i++)
        {
            scanf("%lf",&a[i]);
            if(a[i]>max) max=a[i];  //找出评分中的最大值
            if(a[i]<min) min=a[i];    //找出评分中的最小值
            sum=sum+a[i];   //所有评分相加
        }
        sum=sum-max-min;  //总分减去最大值和最小值
        score=sum/(n-2);  //求出平均分
        printf("%.2lf\n",score);
    }
    return 0;
}

2015

#include<stdio.h>
int main()
{
    int n,m,i,sum;
    int aver;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        sum=0;     //清洗数据
        aver=0;
        for(i=1;i<n+1;i++) //因为数列的第一项为2,将i的初值赋为1,,方便下面求和
        {
            sum=sum+i*2;   //求和
            if(i%m==0)     
            {
                aver=sum/m;  //m项的平均值
                if(i==n)      //错误所在 输出最后一个数时不用空格
                    printf("%d\n",aver);
                else
                printf("%d ",aver);  //每输出一项就要空格  很多题要用到这种格式
                sum=0;           //将sum置零 最后记得将sum置零
            }

            if(i==n&&(n%m!=0))  //最后不足m个数时,求平均值
                printf("%d\n",sum/(i%m));
        }
    }
    return 0;
}

2016

#include<stdio.h>
int main()
{
    int n,a[100],min,k,temp,i;
    while(scanf("%d",&n)!=EOF)
    {
        if(n==0) break;

            min=99999;
            for(i=0;i<n;i++)
            {
            scanf("%d",&a[i]);
            if(a[i]<min)   //找到最小的值的位置i并用k记录
            {
                min=a[i];
                k=i;
            }
            }
            temp=a[0]; 将k的位置和o的位置上的数交换
            a[0]=a[k];
            a[k]=temp;

        for(i=0;i<n;i++)
        {
            if(i==n-1)
            printf("%d\n",a[i]);
            else
            printf("%d ",a[i]);  注意输出格式
        }
    }

    return 0;
}

2017

#include<stdio.h>
#include<string.h>
int main()
{
    int n,i,lenth,count;
    char str[1000];
    scanf("%d",&n);
    getchar();  
    while(n--)
    {
        count=0;
        gets(str);//scanf不能接受空格、制表符Tab、回车等,而gets能够接受。也
                     // 就是说scanf函数只能读取到空格、制表符Tab、回车的前面,而gets函数可以。重难点
            lenth=strlen(str);
            for(i=0;i<lenth;i++)
            {
                if(str[i]>='0'&&str[i]<='9')
                    count++;
            }

        printf("%d\n",count);
    }
    return 0;
}


2018
解题思路:
第一年:1
第二年:2
第三年:3
第四年:4
第五年:6
第六年:9
第七年:13
第八年:19
第九年:28
第十年:41
上面是利用题目描述推得的数据
观察规律:
利用数组解决:
0号位置不用,将1到4号位分别存入1,2,3,4
最后可以找到规律:当n>4时
a[i]=a[i-1]+a[i-3];

#include<stdio.h>
int main()
{
    int f(int n);
    int n;
    while(scanf("%d",&n)&&n)
        printf("%d\n",f(n));
    return 0;
}
int f(int n)
{
    if(n<=4)
        return n;
    else
        return f(n-1)+f(n-3);  //不能写成return f(n)=f(n-1)+f(n-3)  //递归问题,多多反思
}


2019

#include<stdio.h>
int main()
{
    int n,m;
    int a[1000],i,j;
    while(scanf("%d%d",&n,&m)!=EOF&&n&&m)
    {
        for(i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
        }
        for(i=0;i<n;i++)
        {
            if(a[i]>=m)
            {
                for(j=n;j>i;j--)
                {
                a[j]=a[j-1];
                }
                a[i]=m;
                break;  //记得break
            }
            else
            a[n]=m;
        }
        for(i=0;i<n+1;i++)
        {
            if(i==n)
                printf("%d\n",a[i]);
            else
                printf("%d ",a[i]); //标准格式
        }
    }
    return 0;
}

2020

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int n,i,j,temp;
    int a[100];
    while(scanf("%d",&n)!=EOF&&n)
    {
        for(i=0;i<n;i++)
            scanf("%d",&a[i]);
        for(i=0;i<n;i++)
        {
            for(j=0;j<i;j++)
            {
                if(abs(a[i])>=abs(a[j]))   //这里的排序方法没有选的很好
                {
                    temp=a[i];
                    a[i]=a[j];
                    a[j]=temp;
                }
            }
        }

        for(i=0;i<n;i++)
        {
        if(i==n-1)
            printf("%d\n",a[i]);
        else
            printf("%d ",a[i]);
        }
    }
    return 0;
}

2021

#include<stdio.h>
int main()
{
    int n,count,m;
    while(scanf("%d",&n)!=EOF&&n)
    {
        count=0;
        while(n--)
        {
            scanf("%d",&m);
            count+=(m/100+m%100/50+m%50/10+m%10/5+m%5/2+m%5%2); //m%5%2这里要小心 我当时在这里找了好久的bug
        }
        printf("%d\n",count);
    }
    return 0;
}

2022

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int a[100][100];
    int m,n,i,j,max,x,y;
    while(scanf("%d%d",&m,&n)!=EOF)
    {
        max=0;
        for(i=0;i<m;i++)
        {
            for(j=0;j<n;j++)
           {
            scanf("%d",&a[i][j]);
            if(abs(a[i][j])>max) //找到绝对值最大的数,并记录该行列的值
            {
                max=abs(a[i][j]);
                x=i;
                y=j;
            }
           }
        }
        printf("%d %d %d\n",x+1,y+1,a[x][y]);
    }
    return 0;
}

2023
2024

#include<stdio.h>
#include<string.h>
int main()
{
    int n,i,count,lenth;
    char str[100];
    scanf("%d",&n);

        getchar();
        while(n--)
        {
            count=0;
            gets(str);
            lenth=strlen(str);
                if((str[0]>=65&&str[0]<=90)||str[0]=='_'||(str[0]>=97&&str[0]<=122))  //开头只能为下划线或者字母
                {
                    for(i=0;i<lenth;i++)
                        if((str[i]>=65&&str[i]<=90)||str[i]=='_'||(str[i]>=97&&str[i]<=122)||(str[i]>=48&&str[i]<=57)) //标识符只能由下划线数字字母构成
                            count++;
                        if(count==lenth)
                        printf("yes\n");
                        else
                        printf("no\n");
                }else
                printf("no\n");
        }

    return 0;
}

2025

#include<stdio.h>
#include<string.h>
int main()
{
    char str[100];
    int lenth,i,max;

    while(gets(str))
    {
    lenth=strlen(str);
    max=0;
    for(i=0;i<lenth;i++)
    {
        if(str[i]>max)
            max=str[i];
    }
    for(i=0;i<lenth;i++)
    {
        printf("%c",str[i]);
        if(str[i]==max)
        printf("(max)");
    }
    printf("\n");
    }
    return 0;
}

2026

#include<stdio.h>
#include<string.h>
int main()
{
    char str[100];
    int lenth,i;
    while(gets(str))
    {
        lenth=strlen(str);
        
        str[0]=str[0]-32;  //第一个字母前面没有空格只能手动变成大写
        for(i=0;i<lenth;i++)
        {
            if(str[i]==' ')
                str[i+1]=str[i+1]-32;
        }
        for(i=0;i<lenth;i++)
        printf("%c",str[i]);
        printf("\n");
    }
    return 0;
}

2027

#include<stdio.h>
#include<string.h>
int main()
{
    int n,i,lenth;
    int a,b,c,d,e;
    char str[100];
    scanf("%d\n",&n);  
    while(n--)
    {
        
        gets(str);
        a=0,b=0,c=0,d=0,e=0;
        lenth=strlen(str);
        for(i=0;i<lenth;i++)
        {
            if(str[i]=='a') a++;
            if(str[i]=='e') b++;
            if(str[i]=='i') c++;
            if(str[i]=='o') d++;
            if(str[i]=='u') e++;
        }
        printf("a:%d\n",a);
        printf("e:%d\n",b);
        printf("i:%d\n",c);
        printf("o:%d\n",d);
        printf("u:%d\n",e);
        if(n!=0)
        printf("\n");

    }
    return 0;
}

2028
该题有两种方法,第一种为用函数调用的方法求最小公倍数、最大公约数

#include<stdio.h>
int main()
{
    int a[100];
    int i,n;
    int  Gcd(int  m, int  n);
    long long Lcm(long long m, long long n);
    while(scanf("%d",&n)!=EOF)
    {
        for(i=0;i<n;i++)
        scanf("%d",&a[i]);

    for(i=0;i<n;i++)
    {
        a[0]=Lcm(a[0],a[i]);
    }
    printf("%d\n",a[0]);
    }
}

int Gcd(int m, int  n) //辗转相除法,求最大公约数  //这个不用long long类型 取余时一定不会越界 
{
    return m == 0 ? n : Gcd(n % m, m);
}

long long Lcm(long long m, long long n) //最小公倍数 // 这里可能会出现越界的情况
{
    return (m * n / Gcd(m, n));
}

另外一种方法 取数组中最大的数,逐渐累加,直到能够将所有数取余都等于0

#include<stdio.h>
int main()
{
    int a[500];
    int i,n,max;
    while(scanf("%d",&n)!=EOF)
    {
        max=0;
        for(i=1;i<=n;i++)
        {
        scanf("%d",&a[i]);
        if(a[i]>=max)
        max=a[i];
        }
    for(i=1;i<=n;i++) //用这种方法i一定要设置为1,否则i在循环时会跳过第一个数
    {
        if(max%a[i]!=0)
        {
            max++;
            i=0;
        }
    }
    printf("%d\n",max);
    }
    return 0;
}

2029

#include<stdio.h>
#include<string.h>
int main()
{
    char str[100];
    int i,j,n,lenth;
    scanf("%d",&n);
    getchar();
        while(n--)
        {
            gets(str);
            lenth=strlen(str);
            i=0,j=lenth-1;
            while(i<j)
            {
                if(str[i]==str[j])
                {
                    i++;
                    j--;
                if(j-i==2||(j-i==1))
                    printf("yes\n");
                }
                else
                    {printf("no\n"); break;}
            }
        }
    return 0;
}

2030

#include<stdio.h>
#include<string.h>
int main()
{
    char str[1000];
    int length,count,i,n;
    scanf("%d",&n);
    getchar();
    while(n--)
    {
        gets(str);
        count=0;
        length=strlen(str);
        for(i=0;i<length;i++)   
        {
            if(str[i]<0)   汉字的ascll码都小于0
                count++;
        }
        printf("%d\n",(count+1)/2);
    }
    return 0;
}

2032
杨辉三角

#include<stdio.h>
int main()
{
    int a[100][100];
    int n,i,j;
    while(scanf("%d",&n)!=EOF)
    {
        for(i=1;i<n+1;i++)
        {
            a[i][0]=1;
            for(j=1;j<i;j++)
                a[i][j]=a[i-1][j-1]+a[i-1][j];  //该项的数为上一行上一列的数与上一行这一列的数之和
        }
        for(i=0;i<n+1;i++)
            for(j=0;j<i;j++)
            {
            if(j!=i-1)
            printf("%d ",a[i][j]);
            else
            printf("%d",a[i][j]);
            if(j==i-1)
                printf("\n");
            }
        printf("\n");
    }
    return 0;
}

2040
古希腊数学家毕达哥拉斯在自然数研究中发现,220的所有真约数(即不是自身的约数)之和为:

1+2+4+5+10+11+20+22+44+55+110=284。

而284的所有真约数为1、2、4、71、 142,加起来恰好为220。人们对这样的数感到很惊奇,并称之为亲和数。一般地讲,如果两个数中任何一个数都是另一个数的真约数之和,则这两个数就是亲和数。

你的任务就编写一个程序,判断给定的两个数是否是亲和数

#include<stdio.h>
int main()
{
    int s;
    int m,n,i,sum1,sum2;
    scanf("%d",&s);
    getchar();
    while(s--)
    {
        scanf("%d%d",&n,&m);
        sum1=0,sum2=0;
        for(i=1;i<n;i++)
        {
            if(n%i==0)
                sum1+=i;
        }
        for(i=1;i<m;i++)
        {
            if(m%i==0)
                sum2+=i;
        }
        if(sum1==m&&sum2==n)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}

2042

#include<stdio.h>
int f(int a)
{
    int sum;
    if(a==0)
    sum=3;
    else
    {
        sum=(f(a-1)-1)*2;       //递归的逻辑需仔细体会
    }
    return sum;
}
int main()
{
    int n,num,a;
    scanf("%d",&n);
    while(n--)
    {
        scanf("%d\n",&num); //收费站的个数
        a=f(num);
        printf("%d\n",a);
    }
    return 0;
}

2054
这道题参考了很多答案,最后参考别人的写了一个函数调用的方式解决了

#include<stdio.h>
#include<string.h>
char a[100000],b[100000];
void f(char c[])
{
    int lenth,i,flag;
    lenth=strlen(c);
    flag=0;
    for(i=0;i<lenth;i++)
    {
        if(c[i]=='.')  //检查字符串中是否含有小数点
        {
            flag=1;
            break;
        }
    }
    if(flag==1) //如果含有小数点,则从最后一位开始检查是否为零,如果为零将0删除,方法为用\0覆盖
    {
        for(i=lenth-1;i>=0;i--)
        {
            if(c[i]=='0')
                c[i]='\0';   //将0从字符数组中删除的方法
            else
                break;
                lenth--;  //每删除一个字符,字符串的长度要减一
        }
            if(c[lenth-1]=='.')  //检查最后一位是否为小数点,是小数点就删除
                c[lenth-1]='\0'; 
    }
}
int main()
{
    int  c;
    while(~scanf("%s%s",&a,&b))
    {
        f(a);
        f(b);
    c=strcmp(a,b);
    if(c)
        printf("NO\n");
    else
        printf("YES\n");
    }
    return 0;
}

2055

#include<stdio.h>
int main()
{
    int n,m;
    char letter;
    scanf("%d",&n);
    while(n--)
    {
        getchar();  //%s可以吸收换行符  这里也可以换成scanf("%s%d",&letter,&m)
        scanf("%c%d",&letter,&m);
        if(letter>=65&&letter<=90)
            letter=letter-64;
        if(letter>=97&&letter<=122)
            letter=96-letter;
        printf("%d\n",letter+m);
    }
    return 0;
}

发布了28 篇原创文章 · 获赞 7 · 访问量 1184

猜你喜欢

转载自blog.csdn.net/weixin_44433678/article/details/96029255