文章目录
一、数论是什么
官方解释(百度百科):数论是纯粹数学的分支之一,主要研究整数的性质。整数可以是方程式的解(丢番图方程)。有些解析函数(像黎曼ζ函数)中包括了一些整数、质数的性质,透过这些函数也可以了解一些数论的问题。链接
本菜菜理解:就是学习一些数之间的关系,把原来繁重的代码任务(巨大的复杂度),转换为用巧妙的数学方式,轻易地解出。
一句话解释:知道那些数论结论就很简单
二、数论包含哪些
我所学的数论知识比较微薄,举几个用过的
1.gcd(辗转相除法)
long long gcd(long long a,long long b)
{
if (b==0)
return a;
else return gcd(b,a%b);
}
变型:求a,b最小公倍数
解:a*b/gcd(a,b)
2.exgcd
gcd的延伸,用于求ax+by=c的x,y解。
void exgcd(int a, int b, int &x, int &y)
{
if(a%b==0)
{
x=0; y=1;
return;
}
exgcd(b,a%b,x,y);
t=x; x=y;
y=t-a/b*y;
}
3.快速幂
用于快速求出n的k次方(可用于求逆元)
int n,k;
long long sum=1,m;
cin>>n>>k;
m=n;
while (k!=0)
{
if (k&1==1)
sum*=m;
k=k>>1;
m*=m;
}
cout<<sum;
当然还有很多,写不完了…
三、本专题题解
1.k-rounding
思路:求n和10的k次方的最小公倍数
#include <iostream>
using namespace std;
long long gcd(long long a,long long b)
{
if (b==0)
return a;
else return gcd(b,a%b);
}
int main()
{
long long n,k,k1=1;
int i;
cin>>n>>k;
for (i=0;i<k;i++)
k1*=10;
cout<<n*k1/gcd(n,k1)<<endl;
return 0;
}
2. Fedya and Maths
思路:通过列举可以发现规律,如n的最后两位(n小于10则为n)为4的倍数,则答案为4,否则为0.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s;
cin>>s;
int x,l=s.length();
if (l==1)
x=s[0]-'0';
else
x=s[l-1]-'0'+(s[l-2]-'0')*10;
if (x%4==0) cout<<4<<endl;
else cout<<0<<endl;
return 0;
}
3.Revenge of GCD
题意:求x和y的第k大公因数
思路:先求出x和y的最大公因数,x和y的公因数都是它的因数,再通过列举,求出第k大的因数。
#include <iostream>
#include <algorithm>
#define ll long long
using namespace std;
ll gcd(ll a,ll b)
{
if (b==0)
return a;
else
return gcd(b,a%b);
}
int main()
{
int t;
cin>>t;
while (t--)
{
ll x,y,k;
cin>>x>>y>>k;
ll z=gcd(x,y);
ll i,kk=0;
ll ans[10010]={};
for(i=1;i*i<=z;i++)
{
if(z%i==0)
{
ans[kk++]=i;
if(i*i!=z)
ans[kk++]=z/i;
}
}
if(kk<k)
cout<<-1<<endl;
else
{
sort(ans, ans+kk);
cout<<ans[kk-k]<<endl;
}
}
return 0;
}
四、总结
数论这部分的题,如果你掌握了该题所包含的数论知识,或者找到其中的规律,就很好解出。因此想要把数论题做好,就要多练。