寫在前面:
這篇博客是我在[◹]對 算術基本定理 的研究 中的一部分
整數分解廢馬方法
-
整數分解費馬方法
整數分解費馬方法與費馬小定理無關
原理:
任何一個正整數n都能拆成n==2k*a的形式,其中a為一個奇數
我們在a上搞事情:
若a==c*d (c>d,且顯然cd都是奇數)
那么讓x==(c+d)/2,讓y==(c-d)/2
這里是邏輯上的證明,並不是計算機要實現的內容,根本不考慮丟精的情況(就算考慮了,cd都是奇數,不會丟精)
那么x2-y2==(c2+d2+2c*d)/4-(c2+d2-2c*d)/4==(4c*d)/4==c*d==a
枚舉x2,看看x2-a是不是完全平方數
如果是的話,那么c==x+√(x2-a)和d==x-√(x2-a)就都是a的因子
可以枚舉x2,找出a的所有因子!
有用的性質:
接着上面的證明,x==(c+d)/2,a==c*d
根據基本不等式,(c+d)/2 >= √(cd)
即x2 >= a
在枚舉時x2 >= a時才有解
代碼如下:
C++:
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 int n; 6 int tmp; 7 8 int ponySqrt(int x){ 9 if(x<=0) return -1; 10 return (int)sqrt(x)*(int)sqrt(x)==x? (int)sqrt(x):-1; 11 } 12 13 int main(int argc,char *argv[],char *enc[]) 14 { 15 scanf("%d",&n); 16 17 printf("%d==1",n); 18 19 while(n%2==0){ 20 n/=2; 21 printf("*2"); 22 } 23 24 for(int i=(int)sqrt(n);;++i){ 25 tmp=ponySqrt(i*i-n); 26 if(tmp!=-1){ 27 printf("*%d*%d",i+tmp,i-tmp); 28 n/=(i+tmp); 29 n/=(i-tmp); 30 if(n<=1) break; 31 i=(int)sqrt(n); 32 } 33 } 34 return 0; 35 }
Java:
1 import java.util.Scanner; 2 import java.lang.Math; 3 4 class Pony{ 5 6 static int n,tmp; 7 8 static int ponySqrt(int x){ 9 if(x<=0) return -1; 10 return (int)Math.sqrt(x)*(int)Math.sqrt(x)==x? (int)Math.sqrt(x):-1; 11 } 12 13 public static void main(String[] args) throws Exception 14 { 15 Scanner cin=new Scanner(System.in); 16 17 n=cin.nextInt(); 18 19 System.out.printf("%d==1",n); 20 21 while(n%2==0){ 22 n/=2; 23 System.out.printf("*2"); 24 } 25 26 for(int i=(int)Math.sqrt(n);;++i){ 27 tmp=ponySqrt(i*i-n); 28 if(tmp!=-1){ 29 System.out.printf("*%d*%d",i+tmp,i-tmp); 30 n/=(i+tmp); 31 n/=(i-tmp); 32 if(n<=1) break; 33 i=(int)Math.sqrt(n); 34 } 35 } 36 } 37 }