鱼C小甲鱼 - c语言 - [阶段考核] 第一阶段考核

Source

鱼C小甲鱼 - c语言

[阶段考核] 第一阶段考核


大概是到拾遗部分的知识考核,个人觉得蛮简单的
版权属于:bbs.fishc.com
动动手: 以下所有题目都可以很快计算出答案(最多也不超过 3 秒) 如果你的代码需要很长的时间来计算,说明需要调整你的算法

最后,不要试图先看答案,这样对你没啥好处!

注:本期阶段考核主要为了提升你对数学逻辑思维的能力,做不出也没关系噢(不影响接下来的学习)

0.请编写程序,计算出 1000 以下的自然数中,属于 3 或 5 的倍数的数字之和。

10 以下的自然数中,属于 3 或 5 的倍数有 3, 5, 6, 9,它们的和是 23。

我的代码如下:

#include <stdio.h>
int main() {
    
      
	int i,s = 0;
	for (i = 1; i < 1000; i++) {
    
      
		if ((i % 3 == 0) || (i % 5 == 0))
			s += i;
	}
	printf("和为%d\n",s);

答案的代码如下:

#include <stdio.h>

int main()
{
    
      
        int i, sum = 0;

        for (i = 0; i < 1000; i++)
        {
    
      
                if (!(i % 3) || !(i % 5))
                {
    
      
                        sum += i;
                }
        }

        printf("%d\n", sum);

        return 0;
}


1. 请编写程序,找出斐波那契数列中数值不超过 4 百万的项,并计算这些项中值为偶数的项之和。

斐波那契数列中,从第三项开始,每一项被定义为前两项的数字之和。
从 1 和 2 开始,斐波那契数列的前 10 项应该是这样:1, 2, 3, 5, 8, 13, 21, 34, 55, 89, …

我的代码如下:

#include <stdio.h>
int main()
{
    
      
	int i, s = 0;
	int a = 1, b = 2, c = 0;
	for (i = 1; i <= 6; i++) {
    
      
		if (!(b % 2))
			s += b;
		c = a + b;
		a = b;
		b = c;
	}
	printf("和为%d\n", s);
	return 0;
}

答案的代码如下:

#include <stdio.h>

int main()
{
    
      
        long a = 1, b = 2, c, sum = 0;

        do
        {
    
      
                if (!(b % 2))
                {
    
      
                        sum += b;
                }
                c = a + b;
                a = b;
                b = c;
        } while (c < 4000000);

        printf("%ld\n", sum);

        return 0;
}


2. 编写一个程序,求解 600851475143 的最大质数因子是多少?

每个合数都可以写成几个质数(素数)相乘的形式,这几个质数就都叫做这个合数的质数因子。
比如 13195 的质数因子有 5, 7, 13 和 29。

题目要求找出最大的回文数,并且是由两个三位数相乘。我们不妨先求出两个最大的三位数 999 * 999 的乘积,然后逐个递减判断是否回文数。
如果是回文数,再判断是否可以由两个 3 位数相乘得到……

另外由于数字比较大,需要 long long 以上整型才能存储,而 long long 是 C99 新增加的类型,所以在编译的时候应该加上 -std=c99,即告诉 GCC 使用 C99 标准进行编译。另外 math.h 头文件需要加上 -lm 才能正常编译:

gcc -std=c99 -lm test.c && ./a.out

我的代码如下:

#include <stdio.h>
#include <math.h>
int main()
{
    
      
	long long i, s = 0;
	long long n = 13195;
	for (i = 1; i < n; i++) {
    
      
		if ((n % i==0)) {
    
      
			if (i > s) {
    
      
				s = i;
			}
		}
	}
	printf("最大为%lld\n", s);
	return 0;
}

答案的代码如下:

#include <stdio.h>
#include <math.h>

int main()
{
    
      
        long long i, j, k, l, num = 600851475143;
        _Bool flag = 1;

        for (i = 2, j = num/i; flag != 0; i++, j = num/i, flag = 1)
        {
    
      
                if (i * j == num)
                {
    
      
                        k = sqrt((double)j);
                        for (l = 2; l <= k; l++)
                        {
    
      
                                if (j % l == 0)
                                {
    
      
                                        flag = 0;
                                        break;
                                }
                        }
                        if (flag)
                        {
    
      
                                break;
                        }
                }
        }

        printf("%lld\n", j);

        return 0;
}



3. 找出最大的有由两个三位数乘积构成的回文数。

一个回文数指的是从左向右和从右向左读都一样的数字。最大的由两个两位数乘积构成的回文数是 9009 = 91 * 99。
由于这道题比较难,放点提示给大家吧~
提示:判断一个数是否为回文数,你可以先求该数的倒置数(比如 123 的倒置数是 321),如果倒置数等于本身,那么就说明这是一个回文数。

我的代码如下:

#include <stdio.h>
int main()
{
    
      
	long  i, s = 0;
	long  a, b, c;
	for (i = 999*999; i > 100000; i--) {
    
      
//		为什么用100000呢 
//因为是求最大的,所以排除了100x100=10000这类五位数来进行运算
		//		printf("%ld\n",i); //测试运行
		a = i;			//储存i值
		b = a % 1000;	//储存i后三位
		c = a / 1000;	//储存i前三位
		b = (b / 100) + (b % 10) * 100 + ((b % 100) - (b % 10));
		//将i前三位数调转 呃可能有更简单的方法我暂时还没想到
		if (b == c) {
    
      
			s = a;
			break;
		}
	}
	printf("最大回文数为%ld", s);
	return 0;
}

答案的代码如下:

#include <stdio.h>

int main()
{
    
      
        int i, j, target, invert = 0, num = 998001; // 999 * 999

        for ( ; num > 10000; num--)
        {
    
      
                // 先求倒置数
                target = num;
                invert = 0;
                while (target)
                {
    
      
                        invert = invert * 10 + target % 10;
                        target = target / 10;
                }

                // 如果跟倒置数一致,说明该数是回文数
                if (invert == num)
                {
    
      
                        for (i = 100; i < 1000; i++)
                        {
    
      
                                if (!(num % i) && (num / i >= 100) && (num / i < 1000))
                                {
    
      
                                        goto FINDIT;
                                }
                        }
                }
        }

FINDIT: printf("结果是%d == %d * %d\n", num, i, num / i);

        return 0;
}


总结

第一次写博客所以test一下,感觉和微信号推文有点相像 意识到自己c的基础还是不太扎实啊,今后还要加把劲,继续努力呀( ̄▽ ̄)"