C/C++语言基础进阶算法备赛面试 经典、实用、趣味 程序设计编程300例精解每日一练第32天

前言:

备赛蓝桥杯,大学电子设计大赛,C语言提高,算法准备,定位大厂刷题,所以每天一练,不是很适合新手,适合长期规划有一定基础的同学跟上,每日文档由三部分组成,基础题(适合备赛国二),趣味题(适合有兴趣的同学),经典算法题(适合更高要求)组成。当然本意是记录自己训练的过程,基础题基本能做出来,能给自己一个正面回馈,趣味题可以培养兴趣,经典算法题用于真正来训练自己,开眼见长见识,在遇到困难的问题有更好的解决办法,最关键是每天三个题充分利用了零碎时间,细水才能长流,共勉坚持!!!!

基础题:

32.题目:时间函数举例2

1.程序分析:

2.程序源代码:

/*calculate time*/ 

#include "time.h" 

#include "stdio.h" 

main() 

{ time_t start,end; 

int i; 

start=time(NULL); 

for(i=0;i<3000;i++) 

{ printf("\1\1\1\1\1\1\1\1\1\1\n");} 

end=time(NULL); 

printf("\1: The different is %6.3f\n",difftime(end,start)); 

} 

趣味题:

32.可逆素数 求四位的可逆素数。可逆素数指:一个素数将其各位数字的顺序倒过来构成的反序数也是素数。

*问题分析与算法设计

本题的重点不是判断素数的方法,而是求一个整数的反序数。求反序数的方法是从整数的末尾依次截取最后一位数字,每截取一次后整数缩小10倍,将截取的数字作为新的整数的最后一位(新的整数扩大10倍后加上被截取的数字)。这样原来的整数的数字从低到高被不断地截取,依次作为新的整数从高到低的各位数字。

*程序说明与注释
#include<stdio.h>
#include<math.h>
int num(int number);
int ok(int number);
int main()
{
int i,count;
printf("There are invertable primes with 4 digits: \n");
for(count=0,i=1001;i<9999;i+=2) //穷举全部的奇数
{
if(num(i)) //若是可逆素数,则输出
printf(count%9 ? "%3d:%d" : "%3d:%d\n",++count,i);
}
return 0;
} 
int num(int number)
{
int i,j;
if(!ok(number))return 0; //判断是否为素数
for(i=number,j=0;i>0;i/=10) //按位将整数倒过来,产生反序数
{
j=j*10 + i%10;
}
if(number<j) //若原数小于反序数
{
if(!ok(i)) //判断对应的反序数是否为可逆素数
{
return 0;
}
else
{
return 1; //若是可逆数素数,则返回1
}
}
else
{
return 0; 
}
getchar();
return 0;
}
int ok(int number)
{
int i,j;
if(number%2 ==0) //判断是否为素数
return 0;
j= sqrt((double)number) +1 ; //取整数的平方根为判断的上限
for(i=3;i<j;i+=2)
{
if(number %i ==0) //若为素数则返回1,否则返回0
return 0;
}
return 1;
}
*思考题

求1000以内的孪生素数。孪生素数是指:若a为素数,且a+2也是素数,则素数a和a+2称为孪生素数。

经典算法题:

32.得分排行

说明假设有一教师依学生座号输入考试分数,现希望在输入完毕后自动显示学生分数的排行,当然学生的分数可能相同。
解法这个问题基本上要解不难,只要使用额外的一个排行阵列走访分数阵列就可以了,直接使用下面的程式片段作说明:
for(i = 0; i < count; i++) {
juni[i] = 1;
for(j = 0; j < count; j++) {
if(score[j] > score[i])
juni[i]++;
}
}
printf(“得分\t排行\n”);
for(i = 0; i < count; i++)
printf(“%d\t%d\n”, score[i], juni[i]);

上面这个方法虽然简单,但是反覆计算的次数是n^2,如果n值变大,那么运算的时间就会拖长;改变juni阵列的长度为n+2,并将初始值设定为0,如下所示:
在这里插入图片描述
接下来走访分数阵列,并在分数所对应的排行阵列索引元素上加1,如下所示:
在这里插入图片描述
将排行阵列最右边的元素设定为1,然后依序将右边的元素值加至左边一个元素,最后排行阵列中的「分数+1」」就是得该分数的排行,如下所示:
在这里插入图片描述
这样的方式看起来复杂,其实不过在计算某分数之前排行的人数,假设89分之前的排行人数为x人,则89分自然就是x+1了,这也是为什么排行阵列最右边要设定为1的原因;如果89分有y人,则88分自然就是x+y+1,整个阵列右边元素向左加的原因正是如此。
如果分数有负分的情况,由于C/C++或Java等程式语言无法处理负的索引,所以必须加上一个偏移值,将所有的分数先往右偏移一个范围即可,最后显示的时候记得减回偏移值就可以了。

#include <stdio.h> 
#include <stdlib.h> 
#define MAX 100 
#define MIN 0 

int main(void) { 
    int score[MAX+1] = {0}; 
    int juni[MAX+2] = {0}; 
    int count = 0, i; 

    do { 
       printf("输入分数,-1结束:"); 
       scanf("%d", &score[count++]); 
    } while(score[count-1] != -1);
    count--; 

    for(i = 0; i < count; i++) 
        juni[score[i]]++; 
    juni[MAX+1] = 1; 

    for(i = MAX; i >= MIN; i--) 
        juni[i] = juni[i] + juni[i+1]; 
    printf("得分\t排行\n"); 
    for(i = 0; i < count; i++) 
        printf("%d\t%d\n", score[i], juni[score[i]+1]); 

    return 0; 
} 

后续

有更优秀的解法和更优秀的训练题评论区留言,多交流!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黄黄在深夜里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值