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