寒光博客

PAT 浙大版《C语言程序设计(第3版》题解集合
自己C语言写的ac代码记录 比较清晰的思路会标注,如果有问题欢迎斧正 有些题在自己写完之后,还是去百度看一些别人的...
扫描右侧二维码阅读全文
19
2021/01

PAT 浙大版《C语言程序设计(第3版》题解集合

自己C语言写的ac代码记录 比较清晰的思路会标注,如果有问题欢迎斧正
有些题在自己写完之后,还是去百度看一些别人的写法,发现大多都有一点点晦涩和一些技巧点 细节没有写出来 所以打算自己把刷的题都整理一下在这里了。
太太简单的题没有写入

函数题

练习5-1 求m到n之和 (10分)

int sum(int m,int n)
{
    int sum=0;
    for(int i=m;i<=n;i++){
        sum+=i;
    }
    return sum;
}

记得sum初始化0 for边界包括n

练习5-2 找两个数中最大者 (10分)

int max(int a,int b)
{
    return a>b?a:b;
}

三目运算符直接返回结果。

练习5-3 数字金字塔 (15分)

void pyramid(int n)
{
    for(int i=0;i<n;i++){//外层
        //内层 空格+数字
        for(int j=n-(i+1);j>0;j--)
            printf(" ");
        for(int j=0;j<=i;j++)
            printf("%d ",i+1);
        printf("\n");
    }
}

注意题目 每个数字后都有一个空格
外层循环控制行 里层循环控制列
j=n-(i+1) 是行数对应空格与列数的关系, 自己列个表就出来了
数字的时候 记得包括i本身

习题5-1 符号函数 (10分)

int sign(int x)
{
    return x>0?1:(x==0?0:-1);
}

习题5-2 使用函数求奇数和 (15分)

int even(int n){
    return n%2==0?1:0;
}
int OddSum(int List[] ,int N){
    int sum=0;
    for(int i=0;i<N;i++){
        if(!even(List[i]))//判断返回的是 偶数 因为奇数返回0 !0=1
            sum+=List[i];
    }
    return sum;
}

习题5-3 使用函数计算两点间的距离 (10分)

double dist( double x1, double y1, double x2, double y2 ){
    double a=x1-x2,b=y1-y2;
    return sqrt(a*a+b*b);
}

不用去考虑 a为负数 b 为负数的情况 因为平方都为正。

习题5-4 使用函数求素数和 (20分)

int prime( int p )
{
    if(p<2) return 0;//排除 负数和 0 1 ,若为2 会直接跳过for循环 返回1
    for(int i=2;i<=sqrt(p);i++)//比较暴力的素数取法,跟优化是素数筛子可以博客内搜索
    {
        if(p%i==0) return 0;
    }
    return 1;
}
int PrimeSum( int m, int n )
{
    int res=0;
    while(m<=n){
        if(prime(m)){//是素数 返回1
            res+=m;
        }
        m++;
    }
    return res;
}

习题5-5 使用函数统计指定数字的个数 (15分)

int CountDigit( int number, int digit )
{
    int count=0;
    number=abs(number);//化为正数 因为取余后的数如果被余数为负 结果为负
    if(number==0&&digit==0) return 1;//特判断 0这个数字 且目标数为0
    while(number!=0){
        if(number%10==digit){
            count++;
        }
        number/=10;
    }
    return count;
}

习题5-6 使用函数输出水仙花数 (20分)

注意 是n位数的n次水仙花数

int narcissistic( int number ){
    int t=number;
    int copy=number,n=0;
    while(copy!=0)//先计算这个数的 位数
    {
        n++;
        copy/=10;
    }
    while(t!=0){//然后把每个数字的n次幂在原数中减去 判断是否相等 即结果为0
        number-=pow(t%10,n);
        t/=10;
    }
    if(number==0) return 1;
    return 0;


}
void PrintN( int m, int n ){
    for(int i=m+1;i<n;i++){
        if(narcissistic(i))
            printf("%d\n",i);
    }
}

习题5-7 使用函数求余弦函数的近似值 (15分)

有点问题 有空再补

习题6-1 分类统计字符个数 (15分)【细节】

//letter = 英文字母个数, blank = 空格或回车个数, digit = 数字字符个数, other = 其他字符个数
void StringCount( char s[] )
{
    int i,a,b,c,d;
    a=b=c=d=0;
    for(i=0;s[i]!=0;i++)//这萝莉一个细节 字符串结尾'\0'的ascii为 0 所以判0即可 或者 直接写入 s[i]也可以
    {
        char t=s[i];
        if('a'<=t&&t<='z' || 'A'<=t&&t<='Z') a++;
        else if(t==' '||t=='\n') b++;
        else if(t>='0'&&t<='9')c++;
        else d++;
    }
    printf("letter = %d, blank = %d, digit = %d, other = %d",a,b,c,d);
}

习题6-2 使用函数求特殊a串数列和 (20分)【细节】

在fn计算的时候 是从第二位开始计算 这样就可以先扩倍数再加位数
防止上限为int最大数 产生溢出

int fn(int a,int n)
{
    int x=a;//第一位 
    if(n==1)return x; //特判
    while(--n){
        x*=10;
        x+=a;
    }
    return x;   
}
int SumA(int a,int n)
{
    int i,res=0;
    for(i=0;i<n;i++)
    {
        res+=fn(a,i+1);
    }
    return res;
}

习题6-3 使用函数输出指定范围内的完数 (20分)

没有过低的 时间复杂度要求

int factorsum(int number)
{
    int i=0,res=0;
    for(i=1;i<number;i++){
        if(number%i==0)
            res+=i;
    }
    return res;
}
void PrintPN( int m, int n )
{
    int i=0,count=0,j=0;
    for(int i=m;i<=n;i++){
        if(factorsum(i)==i){//是完数
            printf("%d = 1",i);//第一个数 必为1 为了让后面的格式输出容易一点 所以先输出第一个
            count++;
               for(j=2;j<i;j++)//从第二个开始 规范个数输出
               {
                if(i%j==0)
                 printf(" + %d",j);
               }
            printf("\n");
        }
    }
    if(!count)printf("No perfect number");
}

习题6-4 使用函数输出指定范围内的Fibonacci数 (20分)

斐波那契是从 1 1 开始的

int i;
int fib(int n){//三个变量迭代 适用于单个运算
    int a1=1,a2=1,a3=2;
    if(n==1)return 1; //1 2 特判
    if(n==2) return 1;

    for(i=3;i<=n;i++){

        a3=a1+a2;//1 1 2 3 5 8 13 21
        a1=a2;
        a2=a3;
    }
    return a3;

}
void PrintFN(int m,int n)//数组迭代运算 dp
{
    int a[10002];
    a[1]=1;
    a[2]=1;
    int flag=1;
    for(i=1;i<=10000;i++){
       if(!(i==1||i==2))
        a[i]=a[i-1]+a[i-2];
        if(a[i]>=m&&a[i]<=n)
        {
            if(flag) flag=0;//标志 计算有几个
            else printf(" ");

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

    }
     if(flag)
            printf("No Fibonacci number");
}

习题6-5 使用函数验证哥德巴赫猜想 (20分)

素数算法依旧暴力


int prime(int p)
{
    if(p<2 )return 0;
    for(int i=2;i<p;i++)
    {
        if(p%i==0) return 0;
    }
    return 1;
}
void Goldbach(int n)
{
    for(int i=1;i<n;i++)
    {
        if(prime(i)==1&&prime(n-i)==1)//这样一来就能取到 最小的p
        {
            printf("%d=%d+%d",n,i,n-i);
            break;
        }
    }
}

习题6-6 使用函数输出一个整数的逆序数 (20分)

被余数可以为0 ~ 不过这道题这种写法没有用到

int reverse(int number)
{
    int res=0,flag=1;
    while(number)//150 0*10+5*10 +
    {
        res+=number%10;
        res*=10;
        number/=10;
    }
    res/=10;
    return res;
}

练习8-8 移动字母 (10分)

化繁为简 直接拿出前三个字母

void Shift( char s[] )
{
    char a=s[0],b=s[1],c=s[2];

    int i;
    for(i=0;i<strlen(s)-3;i++)
    {
        s[i]=s[i+3];
    }
    s[i++]=a;//1234
    s[i++]=b;s[i++]=c;
}

习题8-3 数组循环右移 (20分)

int ArrayShift( int a[], int n, int m )
{
    m=m%n;//最小次数
    int b[n];
    for(int i=0;i<n;i++){//初始化拷贝数组
        b[i]=a[i];
    }
    for(int i=m;i<n;i++){//m开始 从索引0开始放入
        a[i]=b[i-m];
    }
    for(int i=0;i<m;i++){//最后把前m个 放入 因为i是取不到m的 所以 n-m+i 不必在减1
        a[i]=b[n-m+i];
    }
}

首先把m降低到最小,排除是n的多倍

习题8-4 报数 (20分)

https://pintia.cn/problem-sets/12/problems/337

void CountOff(int n ,int m, int out[])
{
    //初始化
    for(int i=0;i<n;i++)
        out[i]=-1;
    //count计数 第几个数 ,k是对应的编号
   int count=0,k=1;
    while(k<=n)//所有编号都用完为止
    {

        for(int i=0;i<n;i++)
        {
            if(out[i]!=-1) continue;//已经被编号
            if(out[i]==-1) count++;//未编号 计数
            if(count%m==0)out[i]=k++;//第m个 就喂其编号 改变初始值为编号数
        }
    }
}

外层控制报数 内层一直计数,如果已经算过 就改变初始值,并判断是否是第m个。

本文作者:Author:     文章标题:PAT 浙大版《C语言程序设计(第3版》题解集合
本文地址:https://dxoca.cn/pat/385.html       百度已收录
版权说明:若无注明,本文皆为“Dxoca's blog (寒光博客)”原创,转载请保留文章出处。
Last modification:January 19th, 2021 at 01:13 pm
如果觉得我的文章对你有用,请随意赞赏

Leave a Comment