C语言-翁恺-PTA-81-120课后练习题-03


title: C语言-翁恺-PTA-81-120课后练习题-03
tags:

  • PTA
  • C语言
    description: ’ ’
    mathjax: true
    date: 2024-04-05 22:21:00
    categories:
  • PTA

7-84 连续因子

80-以后的题目感觉都不是很好做

一个正整数 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

鸣谢用户 漏穿雪 补充数据!

代码长度限制

16 KB

时间限制

400 ms

内存限制

错误代码

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>

int main() {
    long n = 0;
    int t = 0,beg=0,sum=0,sumt=0,begt=0;
    int num[1000] = {0};
    scanf("%ld", &n);
    for (int i = 2; i <= n / 2; ++i) {
        if (n % i == 0) {
            num[t++] = i;
            //printf("%d ", i);
        }
    }
    //printf("\nt is %d\nt[22] is %d\n", t,num[t-1]);

    for (int i = 1; i <t; ++i) {
        if (num[i] == num[i - 1]+1) {
            if (i == t - 1) {
                sumt = i - begt+1;
                if (sumt > sum) {
                    beg = begt;
                    sum = sumt;
                }
                begt = i;
            }
        }
        else {
            sumt = i - begt;
            if (sumt > sum) {
                beg = begt;
                sum = sumt;
            }
            begt = i;
        }
    }
    printf("%d\n",sum);
    for (int i = beg; i < beg + sum; ++i) {
        printf("%d", num[i]);
        if (i != beg + sum - 1)    printf("*");
    }
    return 0;
}

柳神的代码

思路

**不用算连续因子最多不会超过12个,也不需要三重循环,两重循环即可,直接去计算当前部分乘积能不能整除N
**分析:1、如果只有一个因子,那么这个数只能为1或者质数。因此我们主要去计算两个及以上因数的情况。
2、在有两个及以上的数连乘中,因数的最大上限为sqrt(N) + 1
3、因此思路就是,不断构造连乘,看连乘的积是否是N的因数,如果是,则看这部分连乘的数的个数是否比已记录的多。
4、用变量first记录连乘的第一个数字,这里我把它赋初值为0,如果在寻找N的因数过程中,first没有改变,那么就表明N是1或者是一个质数~

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<math.h>

long int num, temp;
int main() {
    scanf("%ld", &num);
    int first = 0, len = 0, maxn = sqrt(num) + 1;
    for (int i = 2; i <= maxn; i++) {
        int j;
        temp = 1;
        for (j = i; j <= maxn; j++) {
            temp *= j;
            if (num % temp != 0) break;
        }
        if (j - i > len) {
            len = j - i;
            first = i;
        }
    }
    if (first == 0) {
        printf("1\n%ld", num);
    }
    else {
        printf("%d\n", len);
        for (int i = 0; i < len; i++) {
            printf("%d", first + i);
            if (i != len - 1) printf("*");
        }
    }
    return 0;
}

7-93 水仙花数

水仙花数是指一个N位正整数(N≥3),它的每个位上的数字的N次幂之和等于它本身。例如:153=13+53+33。 本题要求编写程序,计算所有N位水仙花数。

输入格式:

输入在一行中给出一个正整数N(3≤N≤7)。

输出格式:

按递增顺序输出所有N位水仙花数,每个数字占一行。

输入样例:

3

输出样例:

153
370
371
407

错误原因

运行超市,无法通过最后一个检测

抽象的点来了,Pow函数的效率还不如自己写的,自己写一个幂函数即可

错误代码

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<math.h>
int judge(int n,int mi) {
	int sum = 0, t = n;
	while (n) {
		sum += pow(n % 10, mi);
		if (sum > t)	return 0;
		n /= 10;
	}
	if (t == sum)	return 1;
	else return 0;
}
int main() {
	int n = 0;
	scanf("%d", &n);
	for (int i = pow(10, n - 1); i < pow(10, n); ++i) {
		if (judge(i,n))	printf("%d\n", i);
	}
	//if (judge(153))	printf("153\n");
	return 0;
}

正确代码:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<math.h>
int mypow(int a, int b) {
	int sum = 1;
	for (int i = 1; i <= b; ++i) {
		sum *= a;
	}
	return sum;
}
int judge(int n,int mi) {
	int sum = 0, t = n;
	while (n) {
		sum += mypow(n % 10, mi);
		if (sum > t)	return 0;
		n /= 10;
	}
	if (t == sum)	return 1;
	else return 0;
}
int main() {
	int n = 0;
	scanf("%d", &n);
	for (int i = mypow(10, n - 1); i < mypow(10, n); ++i) {
		if (judge(i,n))	printf("%d\n", i);
	}
	//if (judge(153))	printf("153\n");
	return 0;
}

7-110 求符合给定条件的整数集

给定不超过6的正整数A,考虑从A开始的连续4个数字。请输出所有由它们组成的无重复数字的3位数。

输入格式:

输入在一行中给出A。

输出格式:

输出满足条件的的3位数,要求从小到大,每行6个整数。整数间以空格分隔,但行末不能有多余空格。

输入样例:

2

输出样例:

234 235 243 245 253 254
324 325 342 345 352 354
423 425 432 435 452 453
523 524 532 534 542 543

代码长度限制

16 KB

时间限制

400 ms

内存限制

错误原因

没啥好的思路,不太会写

柳神没有写这题,所以我找了一个代码量少的,暴力算法

正确代码

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

int main()
{
	int i, j, k;
	int n;
	int count = 0;
	scanf("%d", &n);
	for (i = n; i <= n + 3; i++)
	{
		for (j = n; j <= n + 3; j++)
			for (k = n; k <= n + 3; k++)
				if (i != j && j != k && i != k)
				{
					count++;
					if (count % 6 == 0)
						printf("%d%d%d\n", i, j, k);
					else
						printf("%d%d%d ", i, j, k);
				}
	}
	return 0;
}

7-117 整数的分类处理

这题我看不懂题目的意思,什么叫

存在整数 K 使之可以表示为 3K+1 的整数的个数、

还有什么叫做

存在整数 K 使之可以表示为 3K+2 的所有整数的平均值(精确到小数点后 1 位)

给定 N 个正整数,要求你从中得到下列三种计算结果:

  • A1 = 能被 3 整除的最大整数
  • A2 = 存在整数 K 使之可以表示为 3K+1 的整数的个数
  • A3 = 存在整数 K 使之可以表示为 3K+2 的所有整数的平均值(精确到小数点后 1 位)

输入格式:

输入首先在第一行给出一个正整数 N,随后一行给出 N 个正整数。所有数字都不超过 100,同行数字以空格分隔。

输出格式:

在一行中顺序输出 A1、A2、A3的值,其间以 1 个空格分隔。如果某个数字不存在,则对应输出NONE

输入样例 1:

8
5 8 7 6 9 1 3 10

输出样例 1:

9 3 6.5

输入样例 2:

8
15 18 7 6 9 1 3 10

输出样例 2:

18 3 NONE

代码长度限制

16 KB

时间限制

400 ms

内存限制

错误原因

看不懂题目

后来看了别人的代码才看懂了题目

中译中如下:

  • A2 = 存在整数 K 使之可以表示为 3K+1 的整数的个数

    这个的意思,就是算,这个数列中除以3取余为1的个数

  • A3 = 存在整数 K 使之可以表示为 3K+2 的所有整数的平均值(精确到小数点后 1 位)

    这个的意思,就是算,这个数列中除以3取余为2 的所有数的平均值

正确代码如下:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<limits.h>
int main()
{	
	double a3 = 0;
	int n = 0, a1 = INT_MIN, a2 = 0,p=0,t=0;
	scanf("%d", &n);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", &p);
		if (p % 3 == 0 && p > a1)	a1 = p;
		else if (p % 3 == 1)	a2++;
		else if(p%3==2){
			a3 += p;
			t++;
		}
	}
	if(t!=0)	a3 = a3 * 1.0 / t;
	//printf("t is %d\na3 is %lf\n", t,a3);
	if (a1 == INT_MIN)printf("NONE ");
	else printf("%d ", a1);
	if (a2 == 0)printf("NONE ");
	else printf("%d ", a2);
	if (a3 == 0)printf("NONE");
	else printf("%.01lf", a3);
	return 0;
}

  • 30
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值