欧拉计划(1-5)

下周开始毕设要进入苦逼开发阶段了,申请这两篇东西就先当4周的工作量顶着吧。
这次分享一些我自己比较感兴趣的东西,给大家推荐一个网站 http://projecteuler.net/problems 这是一个解题网站,提供一系列数学题供用户解答,而且语言不限,用自己最熟悉的就好,题目解答并不难,重点难在如何缩短这些题目的运行时间,在成功解出每道题之后还可以进入该题的社区与各个国家的开发者进行探讨,我想这对大家提高代码运行效率是非常有帮助的,另外英文苦手的同学可以访问欧拉计划的中文翻译站 http://pe.spiritzhang.com ,不过个人建议还是直接读英文原文,因为有些东西翻译过来之后确实比较容易令人误解。
先用其中的第一题作为例子
Problem1:

If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.

Find the sum of all the multiples of 3 or 5 below 1000.

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

找出1000以下的自然数中,属于3和5的倍数的数字之和。

Use C:

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

int main(int argc, const char * argv[])

{


clock_t start, end;

start = clock();

int sum=0;

for(int i = 1;i<1000;i++)

{

if(i%3==0 || i%5==0)

{

sum=sum+i;

}

}

end = clock();


printf("Answer : %d,The best response time : %f s",sum,

(double)(end - start) / (double)CLOCKS_PER_SEC);


return 0;

}

使用穷举法可以很容易得出结论,总耗费时间0.000012s,让我们来试试另外一种方法。

Use C:


#include <stdio.h>

#include <stdlib.h>

#include <time.h>

int main(int argc, const char * argv[])

{

// insert code here...

#define n 3

#define m 5

clock_t start, end;

start = clock();

int num1 = (int)(1000-1)/n*n;

int num2 = (int)(1000-1)/m*m;

int num3 = (int)(1000-1)/(n*m)*n*m;

int sum = (num1/n)*(n+num1)/2 + (num2/m)*(m+num2)/2 - (num3/(n*m))*(n*m+num3)/2;

end = clock();

printf("The number is : %d,spent time : %f s",sum,

(double)(end - start) / (double)CLOCKS_PER_SEC);

return 0;

}

Answer: 233168 The best response time: 0.000001s


可以看出代码要比之前的复杂了许多,但是使用这种等差数列求和的方法

的运算时间只有0.000001s,总共减少了900多次的循环,运行速度提高了12倍,而且如果运算量更大,提高的效率越多。


以后每周会在这里分享五道题,以及自己的算法,如果大家有时间推荐先自己去


编译一下再拿过来对比,如果有更效率的算法,欢迎提出评论进行探讨。




Problem2:

Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:

1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.

斐波那契数列中的每一项被定义为前两项之和。从1和2开始,斐波那契数列的前十项为:

1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

考虑斐波那契数列中数值不超过4百万的项,找出这些项中值为偶数的项之和。

Use C:


#include <stdio.h>

#include <stdlib.h>

#include <time.h>

int main(int argc, const char * argv[])

{

// insert code here...

clock_t start, end;

start = clock();

int n1 = 1;

int n2 = 2;

int sum = 0;

while (n1<4000000&&n2<4000000) {

if(n1 % 2 == 0)

sum = sum+n1;

n1 = n1 + n2;

if(n2 % 2 == 0)

sum = sum+n2;

n2 = n1 + n2;

}


end = clock();

printf("Answer : %d,The best response time: %f s",sum,

(double)(end - start) / (double)CLOCKS_PER_SEC);


return 0;

}


Answer : 4613732,The best response time: 0.000001s


Problem3:

The prime factors of 13195 are 5, 7, 13 and 29.

What is the largest prime factor of the number 600851475143 ?

13195的质数因子有5,7,13和29.

600851475143的最大质数因子是多少?

Use C:


#include <stdio.h>

#include <stdlib.h>

#include <time.h>


int main(int argc, const char * argv[])

{


// insert code here...

clock_t start, end;

start = clock();

long int sum = 600851475143;

for(int i=3; i<sum; )

{

if(sum%i==0)

sum/=i;

else i+=2;

}

end = clock();

printf("Answer : %ld,The best response time: %f s",sum,

(double)(end - start) / (double)CLOCKS_PER_SEC);

return 0;

}


Answer : 6857,The best response time: 0.000042 s


Problem4:

A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 99.

Find the largest palindrome made from the product of two 3-digit numbers.

一个回文数指的是从左向右和从右向左读都一样的数字。最大的由两个两位数乘积构成的回文数是9009 = 91 * 99.

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

Use C:


#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <time.h>


int main(int argc, const char * argv[])

{

clock_t start, end;

start = clock();


int mul = 0;

int max = 0;

char a[7];

for(int i = 999 ; i > 99 ; i--)

{

for(int j = 990 ; j > 99 ; j-=11)

/*

我们把回文数的构成可以拆分成这样:

100000a + 10000b + 1000c + 100c + 10b + a

=100001a + 10010b + 1100c


=11(9091a + 910b + 100c)

所以可以看出回文数是一定能够被11整除的

*/

{

mul = i * j;

sprintf(a, "%d", mul);


if(a[0]==a[5]&&a[1]==a[4]&&a[2]==a[3])

{

if(mul > max)

{

max = mul;

}

}

}

}

end = clock();

printf("Answer : %d,The best response time: %f s",max,

(double)(end - start) / (double)CLOCKS_PER_SEC);

}

Answer : 906609,The best response time: 0.011134 s


Problem5:

2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.

What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?

2520是最小的能被1-10中每个数字整除的正整数。

最小的能被1-20中每个数整除的正整数是多少?

Use C:


#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <time.h>


int main(int argc, const char * argv[])

{


clock_t start, end;

start = clock();

long int val = 2520;//因为1-20肯定是1-10的倍数,所以这里直接采用能够正好被1-10整除的最小正整数2520做为单位

long int x;

long int y;

for(x = val ; ; x += val)

{

for(y = 19;y > 10 ; y--)

{

if(x % y != 0)

{

break;

}

}

if(y == 10)

{

end = clock();

printf("Answer : %ld,The best response time: %f s",x,

(double)(end - start) / (double)CLOCKS_PER_SEC);

break;

}

}

return 0;

}


Answer : 232792560,The best response time: 0.001288 s








你可能感兴趣的:(C语言,欧拉计划)