大致題意:
給定乙個大數k,k是兩個大素數的乘積的值。
再給定乙個int內的數l
問這兩個大素數中最小的乙個是否小於l,如果小於則輸出這個素數。
高精度求模+同餘模定理
1、 char格式讀入k。把k轉成千進製kt,同時變為int型。
把數字往大進製轉換能夠加快運算效率。若用十進位制則耗費很多時間,會tle。
千進製的性質與十進位制相似。
例如,把k=1234567890轉成千進製,就變成了:kt=[ 1][234][567][890]。
為了方便處理,我的程式是按「區域性有序,全域性倒序」模式存放kt
即kt=[890][567][234][1 ] (乙個中括號代表乙個陣列元素)
2、 素數打表,把10^6內的素數全部預打表,在求模時則列舉到小於l為止。
注意打表不能只打到100w,要保證素數表中最大的素數必須大於10^6,否則當l=100w且k為good時,會因為陣列越界而re,這是因為越界後prime都是負無窮的數,列舉的while(prime[pmin]
3、 高精度求模。
主要利用kt陣列和同餘模定理。
例如要驗證123是否被3整除,只需求模124%3
但當123是乙個大數時,就不能直接求,只能通過同餘模定理對大數「分塊」間接求模
具體做法是:
先求1%3 = 1
再求(1*10+2)%3 = 0
再求 (0*10+4)% 3 = 1
那麼就間接得到124%3=1,這是顯然正確的
而且不難發現, (1*10+2)*10+4 = 124
這是在10進製下的做法,千進製也同理,*10改為*1000就可以了
#include#includeusing namespace std;
const int n=1001000;
char c[105];
int f[35];
int prime[1000000];
int l;
int pn;
void setprime()/*素陣列打表*/
}}bool mod(int m,int k)//高精度k對p求模,因數檢查(整除),又學習了
if(ans) return false;
return true;
}int main()
}k++;
}int s=0;
while(prime[s]=l) cout<<"good"<
POJ 2635(同餘定理)
首先介紹一下同餘定理 所謂的同餘,顧名思義,就是許多的數被乙個數d去除,有相同的餘數。d數學上的稱謂為模。如a 6,b 1,d 5,則我們說a和b是模d同餘的。因為他們都有相同的餘數1。數學上的記法為 a b mod d 可以看出當n常用公式 1 a a mod d 2 a b mod d b a ...
poj2635 同餘定理 素數篩法
題意 給定乙個數,這個數是兩個素數的乘積,並給定乙個限制l,問是否兩個素數中存在小於l的數,若存在輸出較小質數,否則列印 good 思路 1 x a b,a和b都是素數,那麼x只能分解為 1,x 或則 a,b 因為 x 只有四個因子1,a,b,x。3 素數打表,方便快速判斷某個數是否為質數。根據第乙...
POJ 1465 bfs,同餘剪枝
題目大意 給定乙個數n,和m個數,問求n的最小倍數使得這個數的每一位都是那m個數中的 題目解析 開始想的肯定是將這m個數慢慢dfs過去,注意如果bfs過程中如果遇到當前餘數已經被發現就應該剪枝 同餘定理 因為之前那個數肯定小,並且如果可以生成可行解也一定在之前那個數的基礎上 ac include i...