数论
来源:互联网 发布:吉林省互联网 公安软件 编辑:程序博客网 时间:2024/06/03 11:09
数论:
1. 求n^n的最高位数字。1<=N<=1,000,000
(int)a=10^(n*lg(n)-floor(lg(n^n)))
2. 计算比n小的数中与n不互质的数的和%1000000007
n*(n-1)/2-n*phi(n)/2
3. 抽屉原理的运用
抽屉原理本身只是一句废话,不过他的运用却非常强大
现在假设有一个正整数序列a1,a2,a3,a4.....an,试证明我们一定能够找到一段连续的序列和,让这个和是n的倍数,该命题的证明就用到了抽屉原理
我们可以先构造一个序列si=a1+a2+...ai
然后分别对于si取模,如果其中有一个sk%n==0,那么a1+a2+...+ak就一定是n的倍数(该种情况得证)
下面是上一种情况的反面,即任何一个sk对于n的余数都不为0
对于这种情况,我们可以如下考虑,因为si%n!=0
那么si%n的范围必然在1——(n-1),所以原序列si就产生了n个范围在1——(n-1)的余数,于是抽屉原理就来了,n个数放进n-1个盒子里面,必然至少有两个余数会重复,那么这两个sk1,sk2之差必然是n的倍数,
而sk1-sk2是一段连续的序列,那么原命题就得到了证明了
4. 判断n!是否能够被m整除
计算方法是把m进行质因数分解,看下m的每一个质因数是否能够在n!中找到;
n!中间包含了多少个x(x是任意的一个数,不过一般情况下我们都只讨论x为质数),这种问题的答案是:
n/x+n/(x^2)+n/(x^3).....[一直加到x的乘方不超过n],这个定理的证明也非常的简单,这里就不再赘述了
根据以上观点,就可以分别计算m的每一个质因数是否被完全包含,如果有一个没有被包含,那么就不能被整除!
5. 判断组合数C(n,m)的奇偶性
当n&m==m为奇数,反之就是偶数
6.欧几里德扩展
ax+by=c
对于不定方程ax+by=c的通解为:
x=x*c/d+b/d*t
y=y*c/d+a/d*t
当c%gcd(a,b)!=0时,不定方程无解.
7.乘法逆元
ax=1 mod m .可以化成ax+my=1;
8.同余模
(a+b)mod n=(( a mod n) +( b mod n))mod n
(a-b)mod n=((a mod n)-(b mod n)+n)mod n
在减法中,由于a mod n可能小于b mod n,需要在结果上加上n
其他乘除同理
9.根据费马小定理
a^x%p=a^(x%(p-1))%p
10.n=p(1)^num[1]* p(2)^num[2]*….. p(m)^num[m]n的因子数有(num[1]+1)*…(num[m]+1)
11. 点到线段最短距离
语法:
result=mindistance(Point p1,Pointp2,Point q);
参数:
p1、p2:线段的两个端点q:判断点返回值:点q到线段p1p2的距离
源程序
typedef struct
{ double x,y;
} Point;
double mindistance(Point p1,Pointp2,Point q)
{ int flag=1;
double k;
Point s;
if (p1.x==p2.x){s.x=p1.x;s.y=q.y;flag=0;}
if(p1.y==p2.y){s.x=q.x;s.y=p1.y;flag=0;}
if(flag) {
k=(p2.y-p1.y)/(p2.x-p1.x);
s.x=(k*k*p1.x+k*(q.y-p1.y)+q.x)/(k*k+1);
s.y=k*(s.x-p1.x)+p1.y;
}
if(MIN(p1.x,p2.x)<=s.x&&s.x<=MAX(p1.x,p2.x))
return sqrt((q.x-s.x)*(q.x-s.x)+(q.y-s.y)*(q.y-s.y));
else
returnMIN(sqrt((q.x-p1.x)*(q.x-p1.x)+(q.y-p1.y)*(q.y-p1.y)),sqrt((q.x-p2.x)*(q.x-p2.x
)+(q.y-p2.y)*(q.y-p2.y)));
}
12.求两直线的交点
语法:result=mindistance(Pointp1,Point p2,Point q);
通过指针返回结果返回值:1:两直线相交;2:两直线平行
注意:如需要判断两线段交点,检验k 和对应 k1(注释中)的值是否在0~1之间,用在0~1之间的那个求交点
源程序:
typedef struct
{
double x,y;
} Point;
int linecorss(Point p1,Pointp2,Point p3,Point p4,Point *p)
{
double k;
if((p4.x-p3.x)*(p1.y-p3.y)-(p4.y-p3.y)*(p1.x-p3.x)==0&&
(p2.x-p1.x)*(p1.y-p3.y)-(p2.y-p1.y)*(p1.x-p3.x)==0) return 2;
if((p4.y-p3.y)*(p2.x-p1.x)-(p4.x-p3.x)*(p2.y-p1.y)==0) return 0;
k=((p4.x-p3.x)*(p1.y-p3.y)-(p4.y-p3.y)*(p1.x-p3.x))/((p4.y-p3.y)*(p2.x-p1.x)-(p4.x-p3.x)*(p2.y-p1.y));
//k1=((p2.x-p1.x)*(p1.y-p3.y)-(p2.y-p1.y)*(p1.x-p3.x))/((p4.y-p3.y)*(p2.x-p1.x)-(p4.x-p3.x)*(p2.y-p1.y));
(*p).x=p1.x+k*(p2.x-p1.x);
(*p).y=p1.y+k*(p2.y-p1.y);
return 1;//有交点
}
13. 叉乘法求任意多边形面积 语法:result=polygonarea(Point *polygon,int N);
参数:*polygon: 多变形顶点数组 N: 多边形顶点数目 返回值: 多边形面积
注意:支持任意多边形,凹、凸皆可
多边形顶点输入时按顺时针顺序排列
源程序:
typedefstruct { double x,y; } Point; double polygonarea(Point *polygon,int N){ int i,j; double area = 0; for (i=0;i<N;i++) { j = (i + 1) % N; area += polygon[i].x *polygon[j].y; area -=polygon[i].y * polygon[j].x; } area /= 2; return(area < 0 ? -area : area); }
14. 求三角形面积
语法:result=area3(float x1,float y1,float x2,floaty2,float x3,float y3); 参数: x1~3: 三角形3个顶点x坐标 y1~3: 三角形3个顶点y坐标 返回值: 三角形面积
注意需要 math.h
源程序: float area3(float x1,float y1,float x2,float y2,float x3,float y3){ float a,b,c,p,s; a=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); b=sqrt((x1-x3)*(x1-x3)+(y1-y3)*(y1-y3)); c=sqrt((x3-x2)*(x3-x2)+(y3-y2)*(y3-y2)); p=(a+b+c)/2; s=sqrt(p*(p-a)*(p-b)*(p-c)); return s; }
15.两点距离(2D、3D)
语法:result=distance_2d(float x1,float x2,floaty1,float y2); 参数: x/y/z1~ 2: 各点的x、y、z坐标 返回值: 两点之间的距离 注意: 需要 math.h
源程序: floatdistance_2d(float x1,float x2,float y1,float y2) { return(sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))); } float distance_3d(float x1,float x2,floaty1,float y2,float z1,float z2) {return(sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2)));}
16.整数拆分不可重复的个数
longlong data[maxn][maxn];
int main(){
int i,j;
memset(data, 0, sizeof(int)*maxn);
for(i = 0; i< maxn; i++)
data[0][i] = 0;
for(i = 0; i< maxn;i++) {
for(j = 0; j< maxn;j++) {
int sum =j*(j+1)/2;
if(i >sum)
data[i][j]= 0;
else if(i ==sum)
data[i][j]= 1;
else {
if(i ==j)
data[i][j]=1 + data[i][j-1];
else if(i <j) data[i][j]= data[i][i];
else data[i][j]= data[i-j][j-1] + data[i][j-1];
}
}
}
int n;
while(cin>> n)
cout<< data[n][n]<< endl;
return 0;
}
17.整数的无序拆分(可重复)//求出可分解个数
longlong data[MAX][MAX];
int main(){
int i,j;
memset(data, 0, sizeof(int)*MAX);
for(j = 0; j< MAX; j++)
data[0][j] = 0;
for(i = 1; i< MAX;i++) {
for(j = 1; j< MAX;j++) {
if(i ==j)
data[i][j]= data[i][j-1]+1;
else if(i <j)
data[i][j]= data[i][i];
else data[i][j]= data[i][j-1]+data[i-j][j];
}
}
int n;
while(cin>> n)
cout<< data[n][n]<< endl;
return 0;
}
18.整数的无序拆分//列出分解情况
int data[MAX];
int main(){
int i,n;
cin>> n;
for(i = 0; i< n; i++) {
data[i] = 1;
printf("1");
}
printf("\n");
int size =n;
while(size> 1) {
int t, p,r;
t = data[size-1] + data[size-2];
p = t / (data[size-2]+1);
r = t % (data[size-2]+1);
t = data[size-2]+1;
i = size - 2;
size = size - 2 + p;
for(; i< size; i++)
data[i] =t;
data[size-1] += r;
for(i = 0; i< size; i++)
printf("%d", data[i]);
printf("\n");
}
return 0;
}
19.
大整数取模 n mod m ,n<=10^100,m<=10^9
scanf("%s%d",n,&m);
intl=strlen(n);
int ans=0;
for(int i=0;i<l;i++)
ans=(int)(((long long)ans*10+n[i]-'0')%m);
cout<<ans<<endl;
20.幂取模
a^n mod m, a,n,m<=10^9 O(logn)
intpow_mod(int a,int n,int m)
{
if(n==0)
return 1;
int x=pow_mod(a,n/2,m);
long long ans=(long long)x*x%m;
if(n%2==1)
ans=ans*a%m;
return (int)ans;
}
21.ax ≡b(mod n) ax和b除于n有相同的余数,说明ax-b是
n的倍数,所以ax-b=ny,y为倍数,ax-ny=b;
- 数论
- 数论
- 数论
- 数论
- 数论
- 数论
- 数论
- 数论
- 数论
- 数论
- 数论
- 数论 ?
- 数论
- 数论
- 数论
- 数论
- 数论
- 数论
- mybatis逆向工程
- cracking the coding interview 中文版 (程序员面试金典)
- Python 蒙蔽的地方
- 开学倒计时!鑫飞教学一体机,开启“屏”教学时代
- poj3414 Pots【dfs】
- 数论
- 简单记录一下第一个JAVAWEB项目的过程
- java继承各个类构造器加载的顺序
- Git-暂存与提交(笔记)
- MATLAB 文件夹操作管理
- Stretch属性
- 实体类、实体类List↔JSON互转
- 5.S5PV210中看门狗定时器中断实验代码
- JS-多物体运动(所有物体做相同的运动)