本题要求统计给定整数M和N区间内素数的个数并对它们求和。
输入格式:
输入在一行中给出两个正整数M和N( 1 ≤ M ≤ N ≤ 500 1≤M≤N≤500 1≤M≤N≤500)。
输出格式:
在一行中顺序输出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 M,N=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
水仙花数是指一个N位正整数( N ≥ 3 N≥3 N≥3),它的每个位上的数字的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 3≤N≤7)。
输出格式:
按递增顺序输出所有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
待日后看到更多解法再进行补充
输入一个整数,输出每个数字对应的拼音。当整数为负数时,先输出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;
最好还是用第一种方法!
本题目要求读入一个大于1的整数,编程将其分解成若干个质因子(素数因子)积的形式。
输入格式:
大于1的整数一个。
输出格式:
将输入的正整数分解成若干个质因子积的形式,质因子的出现顺序按从小到大排列。如: 30 = 2 ∗ 2 ∗ 2 ∗ 5 30=2*2*2*5 30=2∗2∗2∗5;如果整数本身为质数或素数,直接输出,如: 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=2∗2∗2∗2∗2∗2∗3∗5∗13
我的答案:
#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;
}
运行成功!
本题与数据结构相关,待学习后重新审视