PTA问题回顾

PTA问题回顾

  • 浙江大学版《C语言程序设计(第3版)》题目集
    • 编程题
      • (1) 练习4-11 统计素数并求和 (20 分)
      • (2) 习题4-6 水仙花数 (20 分)
  • 基础编程题目集
    • 编程题
      • (3) 7-25 念数字 (15 分)(整数分解)
  • 中M2021春C、Java入门练习第I段——变量、表达式、分支、循环
      • (4)7-138 质因子分解 (10 分)

注:PTA为PROGRAMMING TEACHING ASSISTANT(程序设计类实验教学辅助平台),不同于PAT,关于PAT会再开一篇博客

浙江大学版《C语言程序设计(第3版)》题目集

编程题

(1) 练习4-11 统计素数并求和 (20 分)

本题要求统计给定整数M和N区间内素数的个数并对它们求和。

输入格式:
输入在一行中给出两个正整数M和N( 1 ≤ M ≤ N ≤ 500 1≤M≤N≤500 1MN500)。

输出格式:
在一行中顺序输出M和N区间内素数的个数以及它们的和,数字间以空格分隔。

输入样例:

10 31

输出样例:

7 143

我的答案

#include 

int main()
{
    int M,N;
    int isprime=1;
    int sum=0,n=0;
    scanf("%d %d",&M,&N);
    for(int i=M;i<=N;i++)//遍历M和N之间的所有数
    {
        for(int a=2;a<i;a++)
        {
            if(i%a==0)
            {
                isprime=0;//通过isprime赋值排除合数
                break;
            }
        }
        if(isprime==1)
        {
            sum=sum+i;
            n++;
        }
        isprime=1;
    }
    printf("%d %d",n,sum);
    return 0;
}

提交结果

测试点 提示 结果 分数 耗时 内存
0 sample等价 答案正确 12 2 ms 316 KB
1 M==N,0 答案错误 0 3 ms 204 KB
2 M== N ==素数 答案正确 2 3 ms 304 KB
3 M和N取最大边界 答案错误 0 3 ms 188 KB

错误原因

M , N = 0 M,N=0 MN=0
未进入第二个for循环语句
i s p r i m e = 1 ; isprime=1; isprime=1;
输出为1,1
1显然不是素数

改正
这时只需要在结尾加上一个代码块

if(M==1)
    {
        n=n-1;
        sum=sum-1;
    }

整体代码如下:

#include 

int main()
{
    int M,N;
    int isprime=1;
    int sum=0,n=0;
    scanf("%d %d",&M,&N);
    for(int i=M;i<=N;i++)
    {
        for(int a=2;a<i;a++)
        {
            if(i%a==0)
            {
                isprime=0;
                break;
            }
        }
        if(isprime==1)
        {
            sum=sum+i;
            n++;
        }
        isprime=1;
    }
    if(M==1){
        n=n-1;
        sum=sum-1;
    }
    printf("%d %d",n,sum);

    return 0;
}

当然这是初学C语言时的修改,代码还有很大的改进空间
待日后精进再行回顾 —— 2021.2.5 2021.2.5 2021.2.5

PTA 练习4-11

(2) 习题4-6 水仙花数 (20 分)

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

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

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

输入样例:

3

输出样例:

153
370
371
407

注:这是一道十分经典的C语言题,值得常回顾

我的答案

#include 
#include 
int main()
{
    int N;
    int s=0;
    scanf("%d",&N);
    int a=pow(10,N);//划定N位数的上限
    for(int i=a/10;i<a;i++)
    {
		int x=i;
        int t=i;
        while(x>0)
        {
            t=x%10;
            x/=10;//将i的每一位分离出来
            int b=pow(t,N);
		    s=s+b;
        }
        if(s==i)//题目中所给的水仙花数的条件
        {
            printf("%d\n",s);
        }
        s=0;
    }
    return 0;
}

提交结果

测试点 提示 结果 分数 耗时 内存
0 sample等价, 4 答案正确 11 5 ms 172 KB
1 6, 只有1个 答案正确 3 303 ms 192 KB
2 N==5 答案正确 3 28 ms 216 KB
3 最大N,输出4个 运行超时 0 0 KB

原因分析

第一次做这个题目,还未想到如何用更巧妙的方法减少时间复杂度 —— 2021.2.6 2021.2.6 2021.2.6

浙江大学翁凯老师在他的C语言课给出的解法为:

#include 

int main()
{
    int N;
    scanf("%d",&N);
    int first=1;
    int i=1;
    while(i<N)//这一步循环做出N位数的下限
    {
    	first*=10;
    	i++;
	}
	i=first;
	while(i<first*10)
	{
		int t=i;
		int sum=0;
		do
		{
			int d=t%10;
			t/=10;//将每一位分离出来
			int p=d;
			int j=1;
			while(j<N)//这一步循环做出每一位的N次幂
			{
				p*=d;
				j++;
			}
			sum+=p;
		}while(t>0);
		if(sum==i)//保证水仙花数的条件
		{
			printf("%d\n",i);
		}
		i++;
	}
	return 0;
}

PTA 习题4-6

待日后看到更多解法再进行补充

基础编程题目集

编程题

(3) 7-25 念数字 (15 分)(整数分解)

输入一个整数,输出每个数字对应的拼音。当整数为负数时,先输出fu字。十个数字对应的拼音如下:

0: ling
1: yi
2: er
3: san
4: si
5: wu
6: liu
7: qi
8: ba
9: jiu

输入格式:
输入在一行中给出一个整数,如:1234。

提示:整数包括负数、零和正数。

输出格式:
在一行中输出这个整数对应的拼音,每个数字的拼音之间用空格分开,行末没有最后的空格。如 yi er san si。

输入样例:

-600

输出样例:

fu liu ling ling

答案

#include

int main()
{
	int x;
	scanf("%d",&x);
	
	if(x<0)
	{
		printf("fu ");
		x=-x;
	}
	
	int mask=1;
	int t=x;
	while(t>9)
	{
		t/=10;
		mask*=10;
	}
	
	do{
		int d=x/mask;
		x%=mask;
		mask/=10;
		switch(d){
			case 0:printf("ling");break;
			case 1:printf("yi");break;
			case 2:printf("er");break;
			case 3:printf("san");break;
			case 4:printf("si");break;
			case 5:printf("wu");break;
			case 6:printf("liu");break;
			case 7:printf("qi");break;
			case 8:printf("ba");break;
			case 9:printf("jiu");break;
		}
		if(mask>0)printf(" ");
	}while(mask>0);
	
	return 0;
}

PTA 7-25

注:这道题考查的实则是整数的各个数位的输出

知识点

整数数位的分解有两种办法

法一:

#include

int main()
{
	int x;
	scanf("%d",&x);//输入要分解的x
	int mask=1;
	int t=x;
	while(t>9)
	{
		t/=10;
		mask*=10;//算出x的位数,如1234,mask就为1000
	}
	do{
		int d=x/mask;//从最高位开始将每一位表示出来,如第一次循环中d=1
		x%=mask;//将x的高位去掉,如1234变成了234
		mask/=10;
		printf("%d ",d);
	}while(mask>0);
	return 0;
}

这种做法的思想是从高位往低位依次输出数位

法二:

#include

int main()
{
	int x;
	scanf("%d",&x);
	int t=0;
	do{
		int d=x%10;//将x从低位往高位依次分解
		t=t*10+d;//t就是x数位颠倒后的结果,如12345变为54321;
		x/=10;
	}while(x>0);
	x=t;
	do{
		int m=x%10;//此时将新的x从低向高分解,相当于原来的x从高往低分解
		printf("%d ",m);
		x/=10;
	}while(x>0);
	return 0;
}

这种做法的思想为:先知道x每次mod10得到最低位,再除以10将次低位变为最低位,进行分解;但是这种分解是倒序的,那就先将它正序过来

注:法二只适用于末尾不是0的情况,若个位为0,t不是x的倒序
如700,t=7,最后只会输出7;
如1230,t=321,最后输出为3 2 1;

最好还是用第一种方法!

中M2021春C、Java入门练习第I段——变量、表达式、分支、循环

(4)7-138 质因子分解 (10 分)

本题目要求读入一个大于1的整数,编程将其分解成若干个质因子(素数因子)积的形式。

输入格式:
大于1的整数一个。

输出格式:
将输入的正整数分解成若干个质因子积的形式,质因子的出现顺序按从小到大排列。如: 30 = 2 ∗ 2 ∗ 2 ∗ 5 30=2*2*2*5 30=2225;如果整数本身为质数或素数,直接输出,如: 13 = 13 13=13 13=13

输入样例:

12480 12480 12480

输出样例:

12480 = 2 ∗ 2 ∗ 2 ∗ 2 ∗ 2 ∗ 2 ∗ 3 ∗ 5 ∗ 13 12480=2*2*2*2*2*2*3*5*13 12480=2222223513

我的答案:

#include

int main()
{
    int number;
    int i = 2;
    scanf("%d", &number);
    printf("%d=", number);
    while (number != 1) {
        if (number % i == 0)//判断是否为质因数
        {
            printf("%d", i);
            number = number / i;
            while (number % i != 0)//寻找下一个(可能还是这个数)
            {
                i++;
            }
            if (number != 1)
                printf("*");
        }
    }
    return 0;
}

结果显示:(全部)运行超时
调试后发现,当while已经是1的时候,i还是会一直递增下去,严重浪费时间
所以将其中的第二个while语句修改如下:

while (number % i != 0&&number!=1)            
{
	i++;
}

增加了一个判断条件:number != 1
但是系统判定除了12480这个sample答案正确,其他输入运行超时

于是再次修改代码如下:

#include
int main()
{
	int i=2,k;
	scanf("%d",&k);
	printf("%d=",k);
	while(k>1){
		if(k%i==0){
			printf("%d",i);
			k/=i;
			if(k!=1)
			{
				printf("*");
			}
		}
		else{
			i++;
		}
	}
	return 0;
}

运行成功!

本题与数据结构相关,待学习后重新审视

你可能感兴趣的:(各大oj)