算法1--数学基础

1.最小公倍数(欧几里得算法)

辗转相除法求最大公约数,最小公倍数为输入的两数相乘除以最小公倍数

给定两个正整数,计算这两个数的最小公倍数。

输入描述

输入包含多组测试数据,每组只有一行,包括两个不大于1000的正整数。

输出描述

对于每个测试用例,给出这两个数的最小公倍数,每个实例输出一行。

用例输入 1 

10 14

用例输出 1 

70
#include<bits/stdc++.h>
using namespace std;
int gcd(int x,int y);

int main()
{
	int x,y,m;
	while(scanf("%d %d",&x,&y)!=EOF)
	{
		m=gcd(x,y);
		cout<<x*y/m<<endl;
	}
	return 0;
}

int gcd(int x,int y)
{
	int k;
	while(y!=0)
	{
		k=x%y;
		x=y;
		y=k;
	} 
	return x;
}

2.还是最小公倍数

2个正整数的最小公倍数,大家应该都知道怎么求了,比如,10和14的最小公倍数就是70。

现在增加点难度,如果给你多个正整数,你还会计算最小公倍数吗?

比如,5、7、15这三个数的最小公倍数就是105。

输入描述

输入数据第一行是一个正整数C(C<10),表示有C组测试用例。
接下来C行,每行是一组测试数据。
每组数据首先是一个正整数N(1<N<30),表示本组数据有N个正整数,然后接着是N个正整数。

输出描述

请输出每组数据的最小公倍数,每组数据输出一行。
题目保证所有的结果都在32位整数范围内。

用例输入 1 

2
3 5 7 15
6 4 10296 936 1287 792 1

用例输出 1 

105
10296

 我们可以先求两个数之间最小公倍数,接着求这个最小公倍数与第三个数的最小公倍数

wrong answer1

#include<bits/stdc++.h>
using namespace std;
int gcd(int x,int y);

int main()
{
	int x,y,m,r[100000];
	int t,n,i,a,b,c;
	cin>>t;
	while(t--)
	{
		cin>>n;
		for(i=0;i<n;i++)
			cin>>r[i];
		m=gcd(r[0],r[1]);
		c=r[0]*r[1]/m;
		for(i=2;i<n;i++)
		{
			m=gcd(c,r[i]);
			c=c*r[i]/m;
		}
		cout<<c<<endl;
	}
	return 0;
}

int gcd(int x,int y)
{
	int k;
	while(y!=0)
	{
		k=x%y;
		x=y;
		y=k;
	} 
	return x;
}

 注意:long long类型

AC代码如下

#include<bits/stdc++.h>
using namespace std;
long long gcd(long long x,long long y);

int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int n;
		cin>>n;
		long long res=1,a;
		while(n--)
		{
			cin>>a;
			res=res*a/gcd(res,a);
		}
		cout<<res<<endl;
	}
	return 0;
}

long long gcd(long long x,long long y)
{
	long long k;
	while(y!=0)
	{
		k=x%y;
		x=y;
		y=k;
	} 
	return x;
}

3.计算N的N次幂的个位数

给定一个正整数N,请计算并输出N的N次方的个位数。

输入描述

输入第一行是一个正整数T,表示有T组测试用例。
接下来的T行,每行包含一个正整数N(1<=N<=1,000,000,000)。

输出描述

每组数据都输出N的N次幂的个位数,每组数据输出一行。

用例输入 1 

2
3
4

用例输出 1 

7
6

 注意n非常大,用long long类型

 采用快速幂,注意只输出个位数,所以在原来函数基础上%10

#include<bits/stdc++.h>
using namespace std;
int power(long long a,long long n);
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		long long n,k;
		cin>>n;
		k=power(n,n);
		cout<<k<<endl;
	}
	return 0;
}

int power(long long a,long long n)
{
	long long ans=1;
	while(n)
	{
		if(n%2)	ans=(ans*a)%10;
		a=(a*a)%10;
		n=n/2;
	}
	return ans;
}

 4.人见人爱A^B

求A^B的最后三位数表示的整数。
说明:A^B的含义是“A的B次方”

输入描述

输入数据包含多个测试实例,每个实例占一行,由两个正整数A和B组成(1<=A,B<=10000),如果A=0, B=0,则表示输入数据的结束,不做处理。

输出描述

对于每个测试实例,请输出A^B的最后三位表示的整数,每个输出占一行。

用例输入 1 

2 3
12 6
6789 10000
0 0

用例输出 1 

8
984
1

long long类型,三位数就是对1000求余

#include<bits/stdc++.h>
using namespace std;
long long power(long long a,long long n);
int main()
{
	int a,b;
	while(scanf("%d %d",&a,&b))
	{
		if(a==0&&b==0)
			break;
		else
		{
			long long k;
			k=power(a,b);
			cout<<k<<endl;
		}
	}
	return 0;
}

long long power(long long a,long long n)
{
	long long ans=1;
	while(n)
	{
		if(n%2)	ans=(ans*a)%1000;
		a=(a*a)%1000;
		n=n/2;
	}
	return ans;
}

 5.一个新的斐波那契数列

现在,有一个新的斐波那契数列,定义如下:

F(0) = 7,
F(1) = 11,
F(n) = F(n-1) + F(n-2) (n>=2)

输入描述

输入包含多组测试样例,每组测试样例包含一个整数n(n < 1,000,000)。

输出描述

如果F(n)能够被3整除,请输出"yes",否则请输出"no"。

用例输入 1 

0
1
2
3
4
5

用例输出 1 

no
no
yes
no
no
no

好像做过,用递推做的,也可以找规律

#include<stdio.h>
int flag[1000000]={7,11};
void dabiao();
int main()
{
	int i;
	int n;
	dabiao();
	while(scanf("%d",&n)!=EOF)
	{
		if(flag[n]==0)	printf("yes\n");
		else 			printf("no\n");
	}
	
	return 0;
}
 
void dabiao()
{
	int i;
	for(i=2;i<1000000;i++)
	{
		flag[i]=flag[i-1]+flag[i-2];
		flag[i]=flag[i]%3;///防止数太大超出数据类型范围 
	}
	return ;
}

 6.解方程

给定方程 8∗x4+7∗x3+2∗x2+3∗x+6==y,请计算x在[0,100]范围内的解。

输入描述

输入数据首先是一个正整数T(1<=T<=100),表示有T组测试数据。
接下来T行,每行包含一个实数Y ( fabs(Y) <= 1e10 )。

输出描述

请计算并输出方程在范围[0,100]内的解,结果精确到小数点后4位。
如果无解,则请输出“No solution!”

用例输入 1 

2
100
-4

用例输出 1 

1.6152
No solution!

二分查找的思想

#include<bits/stdc++.h>
using namespace std;
double y;
double f(double x);
int main()
{
	double left,right,mid;
	int t;
	cin>>t;
	while(t--)
	{
		cin>>y;
		if(f(0)<=y&&y<=f(100))
		{
			left=0;
			right=100;
			while(right-left>1e-7)
			{
				mid=(left+right)/2;
				double ans=f(mid);
				if(ans>y)	right=mid-1e-7;
				else  		left=mid+1e-7;
			}
			printf("%.4f\n",(left+right)/2);
		}
		else cout<<"No solution!"<<endl;
	}
	return 0;
}

double f(double x)
{
	return 8*pow(x,4.0)+7*pow(x,3.0)+2*pow(x,2.0)+3*x+6;
}

 

knowledge

 快速幂算法

快速幂运算的递归实现

int power(int a,int n)
{
	int ans;
	if(n==0)	ans=1;//结束条件 
	else
	{
		ans=power(a*a,n/2);//递归调用 
		if(n%2==1)	ans*=a;//n为奇数 
	}
	return ans;
 } 

快速幂运算的非递归实现(循环)

int power(int a,int n)
{
	int ans=1;
	while(n)
	{
		if(n%2)		ans=ans*a;//奇数情况 
		a=a*a;					//底数平方 
		n=n/2;					//指数减半 
	 } 
	return ans;
 } 

二分查找

前提:数据的单调性,从小到大排列

int BiSearch(int a[],int n,int x)
{
	int left=0,right=n-1;
	while(left<=right)//注意=不要少 
	{
		int middle=(left+right)/2;//整数除法 
		if(a[middle]==x)//找到的情况 
			return middle;
		if(x>a[middle])	//如果比中值大 
			left=middle+1;
		else			//如果比中值小 
			right=middle-1;	 
	}
	return -1;
 } 

递归

int BiSearch(int a[],int x,int left,int right)
{
	if(left>right)//注意不能有=号 
		return -1;
	else
	{
		int mid=(left+right)/2;
		if(a[mid]==x)
			return mid;
		else if(x>a[mid])
			return BiSearch(a,x,mid+1,right);
		else if(x<a[mid])
			return BiSearch(a,x,left,mid-1);
	}
	
} 

 三分查找

前提:数据的凸性,不要求可导

LeftThird=(Left*2+Right)/3

RightThird=(Left+Right*2)/3

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值