欧拉题10,11,12,15,16——15分治,16字符加法乘法

欧拉题10

The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.

Find the sum of all the primes below two million.

2000000以下素数的和

//2000000以下素数的和
#include <iostream>


using namespace std;

inline int IsPrime(int arg)
{
	for(int i=2;i<arg;i++)
	{
		if(arg%i==0)
			return 0;
	}
	return 1;
}

int main() 
{
	long long int sum=2;
	int i;
	for(i=3;i<2000000;i+=2)
	{
		if(IsPrime(i)) sum += i;
	}
	cout<<"sum="<<sum<<endl;
	return 1; 
}

 

这个质数和,考虑和有没有越界,而且也没想到很好的办法判断质数,只跳过最基础的2这个因子了

欧拉题11

In the 20×20 grid below, four numbers along a diagonal line have been marked in red.

08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65
52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50
32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70
67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21
24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72
21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95
78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92
16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57
86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58
19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40
04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66
88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48

The product of these numbers is 26 × 63 × 78 × 14 = 1788696.

What is the greatest product of four adjacent numbers in the same direction (up, down, left, right, or diagonally) in the 20×20 grid?

//20*20书矩阵里面连续四数乘积最大的,(连续一排,一列,斜着,)
#include <iostream>
#include <fstream>
using namespace std;

long long int Right(int *n)//计算右侧的
{
	long long int product = 1,i;
	for(i=0;i<4;i++)
	{
		product *= n[i];
	}
	return product;
}
long long int Down(int *n)//计算下面的
{
	long long int product = 1,i;
	for(i=0;i<4;i++)
	{
		product *= n[i*20];
	}
	return product;
}

long long int RightDiag(int *n)//计算右下斜
{
	long long int product = 1,i;
	for(i=0;i<4;i++)
	{
		product *= n[i*21];
	}
	return product;
}
long long int LeftDiag(int *n)//计算左下斜
{
	long long int product = 1,i;
	for(i=0;i<4;i++)
	{
		product *= n[i*19];
	}
	return product;
}
 
void RenewPro(long long int(*p_fun)(int *),long long int &product,int *n,int &count)
{//更新当前最大值
	long long int tmp;
	tmp = p_fun(n);
	if(tmp>product) product=tmp;
	count++;
	return;
}

int main()
{
	int num[20][20];
	
	ifstream f_in;
	f_in.open("Largest_product_in_a_grid.txt",ios::in);
	if(f_in.is_open()) cout<<"open success\n";
	else cout<<"failed"<<endl; 
	for(int i=0;i<20;i++)
		for(int j=0;j<20;j++)
			f_in>>num[i][j];
	cout<<"read over\n";
	/*	for(int i=0;i<20;i++)
	{
		for(int j=0;j<20;j++)
			cout<<num[i][j]<<" ";
		cout<<endl;
	}*/
	f_in.close();
	
	long long int product=1;
	int tmp,i,j;
	int count=0;
	for(i=0;i<20;i++)
	{
		for(j=0;j<20;j++)
		{
			if(j<=16) RenewPro(Right,product,&num[i][j],count);
			if(i<=16) RenewPro(Down,product,&num[i][j],count);
			if(j<=16&&i<=16) RenewPro(RightDiag,product,&num[i][j],count);
			if(j>=3&&i<=16) RenewPro(LeftDiag,product,&num[i][j],count);
		}
	}
	cout<<"size int="<<sizeof(int)<<endl;
	cout<<"count="<<count<<endl;
	cout<<Right(&num[3][3])<<endl;
	cout<<Down(&num[3][3])<<endl;
	cout<<RightDiag(&num[3][3])<<endl;
	cout<<LeftDiag(&num[3][3])<<endl;
	cout<<"product="<<product<<endl;
	
	
		
} 

矩阵搜索一遍,根据位置看能计算哪些值,然后更新最大值。

欧拉题12

The sequence of triangle numbers is generated by adding the natural numbers. So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. The first ten terms would be:

1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...

Let us list the factors of the first seven triangle numbers:

 1: 1
 3: 1,3
 6: 1,2,3,6
10: 1,2,5,10
15: 1,3,5,15
21: 1,3,7,21
28: 1,2,4,7,14,28

We can see that 28 is the first triangle number to have over five divisors.

What is the value of the first triangle number to have over five hundred divisors?

计算前n自然数和(三角数),找到第一个超过500个因子的三角数

 

//找到第一个因子多于500个的三角数
#include <iostream>

using namespace std;
int DivNum(long long int num)
{
	int sum=0;
	long long int i;
	for(i=1;i<=num;i++)
	{
		if(num%i==0) sum++;
	}
	return sum;
}

int main()
{
	long long int tri_num=0;
	long long int i;
	for(i=1;;i++)
	{
		tri_num +=i ;
		if(DivNum(tri_num)>=500) break;
	}
	cout<<"result="<<tri_num<<endl;
} 

欧拉题15

Starting in the top left corner of a 2×2 grid, and only being able to move to the right and down, there are exactly 6 routes to the bottom right corner.

How many such routes are there through a 20×20 grid?

找到方格中路径的个数

一开始想着排列组合C,40,20

 

//第一版,直接计算Cm,n
#include <iostream>
using namespace std;
long long int CAnalyse(long long int m,long long int n)
{
	long long int product=1,i;
	for(i=0;i<n;i++)
	{
		product = product*(m-i)/(i+1);
	}
	return product;
}
int main()
{
	long long int m,n;
	cin>>m>>n;
	cout<<CAnalyse(m,n);


	return 0;
} 

后来百度,可以用分治法解决。也是看到这个题才想起来刷个算法导论学习学习。

到某点的路径,等于到它上面点路径+到它左边点的路径。

//分治法欧拉题15
#include <iostream>
#include <stdlib.h>
#include <memory.h>
using namespace std;
#define N 500
long long int point[N][N];//这里代表的是点,与题目要求的是方块查了1,并且零行零列为空 
int present=1;//当前更新到了第present行(已经更新) 

long long int Calculate(int m,int n)
{
	if(m<=present) return point[m][n];
	int i,j;
	for(i=present+1;i<=m;i++)//那就是第一行算到第m行的点 
	{
		for(j=1;j<N;j++)
		{
			point[i][j] = point[i-1][j]+point[i][j-1];//感觉要考虑边界比较麻烦了,,所以把数组边界置为0吧。 
		}
	}
	present = m;
	return point[m][n]; 
}
int main()
{
	memset(point,0,sizeof(point));//那就是1到1023了,point[0] 行列全认为是不存在吧 
	for(int i=1;i<N;i++) point[1][i] = 1;
	int m,n;
	while(1)
	{
		cin>>m>>n;
		cout<<Calculate(m,n)<<endl;	
	}
		
 
	return 0;
} 

20*20的方格右下角,就是第21,21个点,数组里面0索引的没有使用,所以输入m,n=21即可

答案137846528820

 

然后看16题,就比较懵逼了,算2的1000次,再各个数字求和,,,,这玩意肯定越界了,就写了个字符的乘法,也用到加法,以前写过,,

//string的加法与乘法
#include <iostream>
#include <string>
using namespace std;



string Add(string &a,string &b);
int TypeConfirm(string &arg)
{
	string::iterator it;
	for(it=arg.begin();it!=arg.end();it++)
	{
		if(*it>='0'&&*it<='9') continue;
		else return 0;
	}
	return 1;
}

string MultipleOne(char a,string &b)
{
	string::iterator it;
	string::reverse_iterator rit;
	int in=0,tmp;
	string out ;
	for(rit=b.rbegin();rit!=b.rend()-1;rit++)//到b的第二个字符截止 
	{
		tmp = (int)(*rit-'0')*(int)(a-'0')+in;//乘并加上进位 
		in = tmp/10;//取进位 
		tmp = tmp%10;//取乘结果个位 
		out.insert(it = out.begin(),(char)(tmp+48));//out前面插入乘结果个位 
		
	}
	//处理最前面字符
	 tmp = (int)(*rit-'0')*(int)(a-'0')+in;
	 in = tmp/10; 
	tmp = tmp%10;
	out.insert(it = out.begin(),(char)(tmp+48));
	if(in!=0) out.insert(it = out.begin(),(char)(in+48));
	return out;
}
string Multiple(string &a, string &b)
{
	if(!TypeConfirm(a) || !TypeConfirm(b)) 
	{
		cout<<"type error"<<endl;
		return "type error";
	}
	string out,str_tmp;
	out.clear();
	string::iterator it;
	string::reverse_iterator rit;
	int zero_count=0,i;
	for(rit=a.rbegin();rit!=a.rend();rit++)
	{
		str_tmp = MultipleOne(*rit,b);
		cout<<"str_tmp="<<str_tmp<<endl;
		for(i=0;i<zero_count;i++) str_tmp += "0";
		cout<<"str_tmp_0="<<str_tmp<<endl;;
		out = Add(out,str_tmp);
		cout<<"out="<<out<<endl;
		zero_count++;
	}
	return out;
}

int main()
{
	string str1,str2;
	string::reverse_iterator rit;
	string::iterator it;

	
	//cout<<TypeConfirm(str)<<endl;
	//str.insert(it = str.begin(),'a');
	//cout<<MultipleOne('2',str)<<endl;
	//cout<<"insert="<<str<<endl;
	string out,out_add;
	while(1)
	{
		cin>>str1>>str2;
		out = Multiple(str1,str2);
		cout<<"MUl="<<out<<endl;
		out_add = Add(str1,str2);
		cout<<"ADD="<<out_add<<endl;
	}

	//for(int i=0;i<0;i++) cout<<"test";
	//for(rit=str.rbegin();rit!=str.rend();rit++) cout<<*rit<<endl;
	//char c='2';
	//out<<(int)(c-'0');
	return 0;
}
string Add(string &a,string &b)
{
	if(!a.length())
		return  b;
	else if(!b.length())
		return a;
	string str_out;
	str_out.clear();
	string::iterator it;
	string::reverse_iterator rit_a,rit_b;
	int a_len,b_len,i,in=0,tmp;
	a_len = a.length();
	b_len = b.length();
	if(a_len<b_len)
	{
		string str_swap;
		str_swap = a;
		a = b;
		b = str_swap;
	} 
		
		for(rit_b = b.rbegin(),rit_a = a.rbegin(); rit_b!=b.rend() ; rit_b++,rit_a++)//按照a长度大的情况处理 
		{
			tmp = (int)(*rit_a-'0')+(int)(*rit_b-'0')+in;
			in = tmp/10;//取进位 
			tmp = tmp%10;//取结果个位 
			str_out.insert(it = str_out.begin(),(char)(tmp+48));//out前面插入乘结果个位 
		}
			for(; rit_a!=a.rend() ; rit_a++)
		{
			tmp = (int)(*rit_a-'0')+in;
			in = tmp/10;//取进位 
			tmp = tmp%10;//取结果个位 
			str_out.insert(it = str_out.begin(),(char)(tmp+48));//out前面插入乘结果个位 
		}
		if(in==1) str_out = "1"+str_out;//.insert(it = str_out.begin(),"1");
	
 	return str_out; 
}

结果没算,估计得挺长时间。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值