首页 > 代码库 > 九度 1104 以及 辗转相除法的原理f昂发

九度 1104 以及 辗转相除法的原理f昂发

//方法一
//对每个形如 (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;
}