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; }