//方法一 //对每个形如 (A*a+ B)* a^k的数,前面的A 没有意义的,只有B //才有可能继续被用来作为未来的因子,所以每次只需要保留比a小的B 就够了。代码如下: #include <cstdio> #include <iostream> #include <cstring> using namespace std; #ifdef ONLINE_JUDGE #define FINPUT(file) 0 #define FOUTPUT(file) 0 #else #define FINPUT(file) freopen(file,"r",stdin) #define FOUTPUT(file) freopen(file,"w",stdout) #endif int main() { FINPUT("in.txt"); FOUTPUT("out.txt"); int n,a,k; while(cin>>n>>a) { k = 0; long long int m=1; for(int i=1;i<=n;i++) { m *= i; while(m%a==0) { k++; m/=a; } m %= a; //这一行刚开始没有想好原理,后来看了别人的代码才明白 } cout<<k<<endl; } return 0; }
//方法二的算法思想 //1 先对a 进行质因数分解,得到 a = p1^k1 * p2^k2 * p3^k3..... //2 对每一个质因子p,求 k(p) 使得 n!/p^k == 0 但 n!/p^(k+1) !=0 ,方法 [n/p] + [n/p^2] + [n/p^3] + ....... //3 求所有k(p)/ki中的最小值,其中ki为第一步质因数分解中质因子对应的系数, #include<iostream> using namespace std; bool isPrime(int n) { bool result = true; for (int i=2; i*i <= n; ++i) { if (n%i == 0) { result = false; break; } } return result;#include <cstdio> #include <cmath> int gdc(int a, int b) { int r = b; while (b != 0) { r = a % b; a = b; b = r; } return a; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); #endif int n,a; while (scanf("%d%d", &n, &a) != EOF) { int k = 0; int m = a; int pos = 2; int acc = pos; int t = 2; //m 和 pos的最大公约数 while (pos <= n) { t = gdc(m, acc); if (t == m) { ++k; m = a; acc /= t; } else if (t == acc) { m /= t; acc = ++pos; } else if(t == 1) { //互质 acc = ++pos; } else { m /= t; acc = ++pos; } } printf("%d\n", k); } return 0; } } // get prime number m, s.t. n!/a^m ==0 , n!/a^(m+1) != 0 int getK(int n, int a) { int result = 0; while ( n/a > 0) { result += n/a; n = n/a; } return result; } // get p st n^p=m int getP(int m, int n) { int result = 0; while ( m%n == 0) { ++result; m = m/n; } return result; } int main() { int n, a; while (cin >> n >> a) { int out = 1000; int p1; int p2; for (int i=2; i <= a; ++i) { if (isPrime(i) && a%i == 0) { p1 = getP(a, i); p2 = getK(n, i); out = p2/p1 < out ? p2/p1 : out; } } cout << out << endl; } return 0; }
//方法三: include <cstdio> #include <cmath> int gdc(int a, int b) { int r = b; while (b != 0) { r = a % b; a = b; b = r; } return a; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); #endif int n,a; while (scanf("%d%d", &n, &a) != EOF) { int k = 0; int m = a; int pos = 2; int acc = pos; int t = 2; //m 和 pos的最大公约数 while (pos <= n) { t = gdc(m, acc); if (t == m) { ++k; m = a; acc /= t; } else if (t == acc) { m /= t; acc = ++pos; } else if(t == 1) { //互质 acc = ++pos; } else { m /= t; acc = ++pos; } } printf("%d\n", k); } return 0; }
九度 1104 以及 辗转相除法的原理f昂发,布布扣,bubuko.com
时间: 2024-11-04 02:27:32