project Euler上的一些问题

随便做了几题,还是project first,有空再来做

Number spiral diagonals问题

21  22 23 24  25
20   7   8   9  10
19  6   1   2 11
18   5   4   3  12
17  16 15 14  13
计算对角线的数字之和
看到对角线数值变化是
1+(3+5+7+9)+(13+17+21+25)+(31+37+..)+...+1001*1001
每四个数组成一组,该四个数为等差数列,开始先递增2,再递增4,再递增6,count从3开始算起,count为从3开始的数的个数,
递增2*(count/4+1)

#include<iostream>
using namespace std;
int main(){
	int sum=1;
	int j=3;
	int count =0;
	while(j<=1001*1001){
		count++;
		sum+=j;
		j+=2*(count/4+1);
	}
	cout<<sum<<endl;
}



Maximum path sum II

三角形自顶向下最大的路径和
本质上应该是道动态规划的题目

当需要求得到(i,j)位置的最大路径的时候,(i,j)位置可由(i-1,j-1)或者(i-1,j)位置移动而来
res[i][j]=max(res[i-1][j],res[i-1][j-1])+A[i][j],  边界元素可以多申请数组,事先填充为0,以空间换时间了
实现的代码空间上有点冗余

#include<iostream>
#include<fstream>
using namespace std;
const int m=100;
int A[m+1][m+1];
int res[m+1][m+2];
int max(int i,int j){
	return (i>j)?i:j;
}
int main(){
	ifstream fin("D://triangle.txt");
	memset(res,0,sizeof(int)*(m+1)*(m+2));
	for(int i=1;i<=m;i++){
		for(int j=1;j<=i;j++){
			fin>>A[i][j];
		}
	}
	res[1][1]=A[1][1];
	for(int i=2;i<=m;i++){
		for(int j=1;j<=i;j++){
			res[i][j]=max(res[i-1][j-1],res[i-1][j])+A[i][j];
		}
	}
	int max=res[m][1];
	for(int i=2;i<=m;i++){
		if(max<res[m][i])
			max = res[m][i];
	}
	cout<<max<<endl;

}


Digit fifth powers

开始还以为是五位数等于各个位数的5次方的和,结果提交后错误,发现题目没读清楚
这个数应该有个上界upper bound

x^5 9^5=59049
设有n位,若成立的话   (9^5)*n>10^(n-1),    n势必<7,否则10^(n-1) 将远大于(9^5)*n
设此数上限为9^5*6=354294

#include<iostream>
#include<cmath>
using namespace std;

int main(){
	int digit[6];
	int sum;
	int res =0;
	int high;
	//k is the biggest power less than i with base of 10(10^k<i)
	int k=1;
	for(int i=10;i<=354294;i++){
		high = i/int(pow(10.0,k));
		while(high>0){
			k++;
			high = i/int(pow(10.0,k));
		}
		k--;
		sum=0;
		//calculate every digit
		int remain=i;
		for(int l=k;l>=0;l--){
			digit[l]=remain/int(pow(10.0,l));
			remain-=digit[l]*int(pow(10.0,l));
			sum+=pow(float(digit[l]),5);
		}
		
		if(abs(sum-i)<0.000000001){
			//cout<<i<<endl;
			res+=i;
		}

	}
	cout<<res<<endl;

	

}


problem 13
Work out the first ten digits of the sum of the following one-hundred 50-digit numbers.
#include<fstream>
#include<iostream>
#include<cmath>
#include<iomanip>
using namespace std;

int main(){
	ifstream fin("D://sum.txt");
	long double num;
	long double sum=0.0;
	for(int i=0;i<100;i++){
		fin>>num;
		//cout<<num<<endl;
		sum+=num;
	}
	cout<<setprecision(20)<<sum<<endl;
	return 0;
}



problem11
刚开始觉得这道题目可能有点难度,暂时想不出来,稍微一想其实也不难。
每个点有四个方向,平行向右扩展,垂直向下扩展,沿对角线向右扩展,沿对角线向左扩展,一共四种情况,每一个点均存储一个最大值
What is the greatest product of four adjacent numbers in the same direction (up, down, left, right, or diagonally) in the 20 20 grid
#include<fstream>
#include<iostream>
using namespace std;
int arr[20][20];
int dim=20;
int main(){
	//return value
	int product = 0;
	ifstream fin("D://test3.txt");
	int temp;
	int res = 0;
	for(int i=0;i<20;i++){
		for(int j=0;j<20;j++)
			fin>>arr[i][j];
	}
	for(int i=0;i<20;i++){
		for(int j=0;j<20;j++){
			if(j<dim-3){
				temp=arr[i][j]*arr[i][j+1]* 
					arr[i][j+2]*arr[i][j+3];
				if(res<temp)
					res = temp;
			}
			if(i<dim-3){
				temp=arr[i][j]*arr[i+1][j]*
					arr[i+2][j]*arr[i+3][j];
				if(res<temp)
					res = temp;
			}
			if(i<dim-3&&j<dim-3){
				temp = arr[i][j]*arr[i+1][j+1]*
					arr[i+2][j+2]*arr[i+3][j+3];
				if(res<temp)
					res = temp;
			}
			if(j>=3&&i<dim-3){
				temp=arr[i][j]*arr[i+1][j-1]*
					arr[i+2][j-2]*arr[i+3][j-3];
				if(res<temp)
					res = temp;
			}
			if(product<res)
				product = res;

		}
	}
	cout<<product;
	system("pause");

}


Problem 15

简单的动态规划
Starting in the top left corner of a 2 2 grid, and only being able to move to the right and down
此题有两处易错的点,一是网格应该看成边界上的点2*2的网格相当于3*3的网格点,路径数与网格点的位置有关,走的是网格的点

所以求20*20的网格的路径数相当于在21*21的网格点中找路径
另外由于结果数字可能会超出范围,因此用int无法表示该数据类型,可以改用unsigned __int64之类的数据
下面程序中path[0][1]与path[1][0]的数据是随便设的,只要使两者之和为1,即path[1][1]=1,使到网格点(1,1)只要一条路径即可
#include<iostream>
using namespace std;
const int m=21;
__int64 path[m+1][m+1];

int main(){
	memset(path,0,sizeof(int)*(m+1)*(m+1));
	path[0][1]=0;
	path[1][0]=1;
	for(int i=1;i<=m;i++){
		for(int j=1;j<=m;j++)
			path[i][j]=path[i-1][j]+path[i][j-1];

	}
	cout<<path[m][m]<<endl;
	
}



14  Longest Collatz sequence
brute-force,注意数据类型用_int64之类的存储就行了,否则会溢出

你可能感兴趣的:(project Euler上的一些问题)