PTA日常训练(C语言详细版)

简介: 所谓完数就是该数恰好等于除自身外的因子之和。例如:6=1+2+3,其中1、2、3为6的因子。本题要求编写程序,找出任意两正整数m和n之间的所有完数。

1.找完数


所谓完数就是该数恰好等于除自身外的因子之和。例如:6=1+2+3,其中1、2、3为6的因子。本题要求编写程序,找出任意两正整数m和n之间的所有完数。


输入格式:


输入在一行中给出2个正整数m和n(1<m≤n≤10000),中间以空格分隔。


输出格式:


逐行输出给定范围内每个完数的因子累加形式的分解式,每个完数占一行,格式为“完数 = 因子1 + 因子2 + ... + 因子k”,其中完数和因子均按递增顺序给出。若区间内没有完数,则输出“None”。


输入样例:


2 30


输出样例:


6 = 1 + 2 + 3
28 = 1 + 2 + 4 + 7 + 14


解题代码:


#include <stdio.h>
int main() {
    int m, n, sum;
    int i, j;
    int count = 0;
    scanf("%d %d", &m, &n);
    for (i = m;i <= n;i++) {
        //这里控制的是题目上給的从n到m个数字,注意输入和输出格式
        if (i == 1) {
            continue;
            //一不是完数,如果是有一的话直接跳过一
        }
        sum = 1;//sum计算因数的和,它至少有一个1,所以sum从1开始
        for (j = 2;j < i;j++) {
            if (i % j == 0) {
                //计算因数,如果是取余为0,那么就是因数
                sum = sum + j;
                //将每次的因数加起来求和
            }
        }
            //要判断这个数是不是完数,要是你的因数和等于自己的大小,那么你1就是完数
            if (i == sum) { //是完数
                printf("%d = 1", i);
                for (j = 2;j < i;j++) {
                    if (i % j == 0) {
                        printf(" + %d", j);
                    }
                }
                printf("\n");
                count++;
            }
    }
    //count用来统计有几个完数
    if (count == 0) {
        printf("None\n");
    }
    return 0;
}


2.水仙花数


输入两个3位的正整数m,n,输出[m,n]区间内所有的“水仙花数”。所谓“水仙花数”是指一个3位数,其各位数字的立方和等于该数本身。


输入格式:


测试数据由多组,处理到文件尾。每组测试输入两个3位的正整数m,n(100≤m<n≤999)。


输出格式:


对于每组测试,若[m,n]区间内没有水仙花数则输出“none”(引号不必输出),否则逐行输出区间内所有的水仙花数,每行输出的格式具体参看输出样例。


输入样例:


100 150
100 200


输出样例:


none
153=1*1*1+5*5*5+3*3*3


解题代码:


#include<stdio.h>
#include<math.h>//方便计算后边的立方,也可以自己写一个立方函数,比较简单
//pow(x,y)函数,x的y次幂
/*
思路:
1.将每一位的数字单独摘出来
2.判断是否是完数
注意:他是在一个范围之内,所以要用一个循环来控制变量
注意输入输出格式,它这个是一次要输入多组数据,要是在c++中可以用vector动态申请一个动态二维数组
这里我们加一个循环来模拟控制一波
*/
int main() {
  int m, n;//给了两个变量来接收范围
  int i;  //循环变量
  int sum;//用来判断每个项的立方和
  int b, s, g;//定义三个变量分别表示百位,十位,个位;
  int count = 0;//用来计数
  while (scanf("%d %d", &m, &n) != EOF) {
    //EOF解释;EOF在c语言中表示文本资料的结束,大家可以联想一下我们讲文件的时候判断文件那一块哦
    for (i = m;i <= n;i++) {
      //将百、十、个位都摘出来
      b = i / 100;
      s = i / 10 % 10;
      g = i % 10;
      sum = pow(b, 3) + pow(s, 3) + pow(g, 3);//计算平方和
      //进行比较,判断是否是水仙花
      if (sum == i) {
        printf("%d=%d*%d*%d+%d*%d*%d+%d*%d*%d\n", i, b, b, b, s, s, s, g, g, g);
        count++;//每次有一个水仙花,计数器就加易
      }
    }
    if (count == 0) {
      printf("none\n");
    }
  }
  return 0;
}


3.单词长度


你的程序要读入一行文本,其中以空格分隔为若干个单词,以.结束。你要输出每个单词的长度。这里的单词与语言无关,可以包括各种符号,比如it's算一个单词,长度为4。注意,行中可能出现连续的空格;最后的.不计算在内。


输入格式:


输入在一行中给出一行文本,以.结束


提示:用scanf("%c",...);来读入一个字符,直到读到.为止。


输出格式:


在一行中输出这行文本对应的单词的长度,每个长度之间以空格隔开,行末没有最后的空格。


输入样例:


It's great to see you here.


输出样例:


4 5 2 3 3 4
#include<stdio.h>
/*
使用while(scanf)会运行时间超
思路:每个单词之间是靠空格来隔开,文本结束时候是个‘.’所以在计数的时候结束标志就是一个空格或者一个‘.’
根据提示可以得到输入的格式
我的思路是每次判断,有些人可能会用一个数组将所有的字符都保存起来,这里没有给范围,我感觉有点麻烦
1.一开始我是使用一个while将每次输入进来  while (scanf_s("%c", &c)!='.'),然后超时了,而且最后一个和'.'相连的单词会少算一个字母
所以使用分开输入,采用do while格式
2.判断计数结束,两种情况
这个题要注意多种情况:空句子、有多个连续的空格,只有一个单词,开头和结尾有多个空格
最大的坑是输出格式,第一个的出书格式与其他的不同,所以将他做个标记分开输出
*/
int main() {
    char c;//我用的是每次判断
    int count = 0;//用来判断一个单词有几个字符
    //分开接受字符
    int first = 0;//用来记录第一个单词
    do {
        scanf("%c", &c);
        if (c != ' ' && c != '.') {
            count++;               //计数器,用来计算单词中字母的个数
        }
        else {
            //这种情况就是遇到了空格或者'.'停止计数
            if (first == 0 && count != 0) {
                //这种情况代表第一个单词的情况
                printf("%d", count);
                first = 1;//修改判断条件,第一个单词已经输出了
            }
            else if (count != 0) {
                printf(" %d", count);
            }
            count = 0;
        }
    } while (c != '.');
    return 0;
}


4.猜数字


一群人坐在一起,每人猜一个 100 以内的数,谁的数字最接近大家平均数的一半就赢。本题就要求你找出其中的赢家。


输入格式:


输入在第一行给出一个正整数N(≤104)。随后 N 行,每行给出一个玩家的名字(由不超过8个英文字母组成的字符串)和其猜的正整数(≤ 100)。


输出格式:


在一行中顺序输出:大家平均数的一半(只输出整数部分)、赢家的名字,其间以空格分隔。题目保证赢家是唯一的。


输入样例:


7
Bob 35
Amy 28
James 98
Alice 11
Jack 45
Smith 33
Chris 62


输出样例:


22 Amy
#include<stdio.h>
#include<math.h>
/*
* 首先看这个题的要求,就是计算平均数,然后找最接近的那个,然后将平均数的一半输出 加 这个人的名字
* 注意数字直接用整形就行
思路:
我的思路是:
1.用一个结构体将他的名字和它的数字保存起来
2.拿到所有数字并且求平均值
3.进行比较,比较差的绝对值的大小,绝对值越小的就是要找的节点
4.输出(注意格式)
*/
typedef struct people{
  char name[10];//c语言中没有string类型的变量,
    //所以用个数组来代替一下,名字的长度最多为8,一开始用8,答案部分正确,改成10,还是段错误
  int num;
}s;
#define max 100000   //最多有100名玩家,别管,我猜的,过不去就再加,然后就真的不对了,段错误,
//之后逐次加0,直到对,毕竟数组就俩,不是上边那个就是下边这个
int main() {
  s player[max]; //初始化100个玩家,就要有100个结构体,先开辟空间再说
  int N;//有N名玩家
  int i;
  double avg,sum=0;//代表一开始计算的平均数,为了精确使用double
  int simavg;//代表最后要输出的一半的平均数
  scanf("%d", &N);
  for (i = 0;i < N;i++) {
    scanf("%s %d", player[i].name, &player[i].num);
    sum += player[i].num;
    //这一步结束我们就拿到了所有的信息
  }
  //计算平均数
  avg = sum / N;
    simavg = (int)avg / 2;
  //每个数字与平均数的一半的差的绝对值进行比较,方法类似冒泡排序,有人比他小就换位置
  //假设第一个是最小的
  s min = player[0];
  for (i = 1;i < N;i++) {
    if (fabs(player[i].num - simavg) < fabs(min.num - simavg)) {
      //s temp ;
      //temp = min;
      min = player[i];
      //player[i] = temp;
      交换两个结构体
    }
  }
  //循环结束后,最小的就是第一个啦
  printf("%d %s", simavg, min.name);
  return 0;
}


5.连续因子

一个正整数 N 的因子中可能存在若干连续的数字。例如 630 可以分解为 3×5×6×7,其中 5、6、7 就是 3 个连续的数字。给定任一正整数 N,要求编写程序求出最长连续因子的个数,并输出最小的连续因子序列。


输入格式:


输入在一行中给出一个正整数 N(1<N<231)。


输出格式:


首先在第 1 行输出最长连续因子的个数;然后在第 2 行中按 因子1*因子2*……*因子k 的格式输出最小的连续因子序列,其中因子按递增顺序输出,1 不算在内。


输入样例:


630


输出样例:


3
5*6*7
#include<stdio.h>
#include<math.h>
/*
思路:
这个题就是一个变形的阶乘
先判断是否否和,再返回去求长度
*/
int main() {
  int i, j;
  int N;//输入的正正数
  int  sum;//用来保存累乘的结果
  int len = 0;//用来记录长度
  int start = 0;//做好记录,要记录最先开始的那个元素,方便之后进行输出
  //累乘只需要到根号N,这样时间复杂度只是logN;因为当数字大于根号N
  //的时候肯定还有一个数字大于根号N,导致积大于根号N。
  scanf("%d", &N);
  for (i = 2;i <= sqrt(N)+1;i++) {
    //控制第一个起点
    sum = 1;
    for (j = i;j <= sqrt(N)+1;j++) {//控制从i个数字之后的阶乘
      sum *= j;
      if (N % sum == 0) {
        //要判断是否是最长的那个序列,如果不是要做一个更新
        if (j - i + 1 > len) {
          //这里为啥是j-i+1就是因为这个是从i开始阶乘,到j结束的一个长度
          len = j - i + 1;//做好更新
          start = i;
        }
      }
      else break;//如果阶乘出现了不为0的情况直接退出这次循环,因为如果一个数字被2*3*4整除,那么他也可以被2*3整除
    }
  }
  if (start != 0) {//说明一个都没找到
    printf("%d\n", len);
    printf("%d", start);
    for (i = start + 1;i < start + len;i++) {
      printf("*%d", i); 
  }
    }
  else {//有多个,输出最长的len和从start开始的序列
     start = N;//只有从N开始一个长度了
    len = 1;
    printf("%d\n", len);
    printf("%d", N);
    }
  return 0;
}


6.A除以B(PTA)


真的是简单题哈 —— 给定两个绝对值不超过100的整数A和B,要求你按照“A/B=商”的格式输出结果。


输入格式:


输入在第一行给出两个整数A和B(−100≤A,B≤100),数字间以空格分隔。


输出格式:


在一行中输出结果:如果分母是正数,则输出“A/B=商”;如果分母是负数,则要用括号把分母括起来输出;如果分母为零,则输出的商应为Error。输出的商应保留小数点后2位。


输入样例1:


-1 2


输出样例1:


-1/2=-0.50


输入样例2:


1 -3


输出样例2:


1/(-3)=-0.33


输入样例3:


5 0


输出样例3:


5/0=Error
#include<stdio.h>
/*
思路:
本题的关键是输出的格式与输入的变量类型
输入的是有符号整形    int
输出的是有符号类型的浮点类型,并且保存小数点后两位  float
1.判断分母是否为0(就是除数)如果为0,就要上一个括号,分母为0就输出Error
*/
int main() {
  int A, B;
  float sum;//
  scanf("%d %d",&A,&B);//这里定义两个变量
  sum = (float)A / B;
  if (B == 0) {
    printf("%d/%d=Error",A,B);
  }
  else if (B < 0) {
    printf("%d/(%d)=%.2f",A,B,sum);
  }
  else {
    printf("%d/%d=%.2f", A, B, sum);
  }
  return 0;
}
目录
相关文章
|
4月前
|
存储 C语言 C++
PTA—C语言期末复习(选择题)
PTA—C语言期末复习(选择题)
|
4月前
|
C语言
PTA—C语言期末复习(判断题)
PTA—C语言期末复习(判断题)
|
6月前
|
C语言
pta浙大版《C语言程序设计(第3版)》 习题6-4 使用函数输出指定范围内的Fibonacci数 (20分)
pta浙大版《C语言程序设计(第3版)》 习题6-4 使用函数输出指定范围内的Fibonacci数 (20分)
|
6月前
|
C语言
PTA 浙大版《C语言程序设计(第3版)》题目集 习题8-4 报数 (20分)
PTA 浙大版《C语言程序设计(第3版)》题目集 习题8-4 报数 (20分)
|
6月前
|
C语言
PTA 浙大版《C语言程序设计(第3版)》题目集 习题8-6 删除字符 (20分)
PTA 浙大版《C语言程序设计(第3版)》题目集 习题8-6 删除字符 (20分)
|
6月前
|
C语言
pta 浙大版《C语言程序设计(第3版)》题目集 习题6-6 使用函数输出一个整数的逆序数 (20分)
pta 浙大版《C语言程序设计(第3版)》题目集 习题6-6 使用函数输出一个整数的逆序数 (20分)
|
6月前
|
C语言
C语言部分期末答案(来自PTA)
C语言部分期末答案(来自PTA)
|
6月前
|
存储 C语言
[C语言/PTA] 学生成绩链表处理
[C语言/PTA] 学生成绩链表处理
121 0
|
6月前
|
存储 C语言
[C语言/PTA] 建立学生信息链表
[C语言/PTA] 建立学生信息链表
124 0
|
6月前
|
存储 C语言
[C语言/PTA] 单链表结点删除
[C语言/PTA] 单链表结点删除
111 0