牛客網 上海交通大學 整除問題

整除問題

時間限制:1秒 空間限制:65536K 熱度指數:2120
算法知識視頻講解
校招時部分企業筆試將禁止編程題跳出頁面,爲提前適應,練習時請使用在線自測,而非本地IDE。

題目描述

給定n,a求最大的k,使n!可以被a^k整除但不能被a^(k+1)整除。

輸入描述:

兩個整數n(2<=n<=1000),a(2<=a<=1000)

輸出描述:

一個整數.
示例1

輸入

複製
6 10

輸出

複製
1

思路

數據太大不可能直接計算,首先想到的思路應該是將n!和a分解成質因子的冪指數形式。a的分解很簡單,關鍵是在於n!的分解。
考慮某個質因子p,則在1到n中一定有n/p個數,每個數至少向p的冪次貢獻了1。(因爲至少有n/p個p的倍數屬於1到n,而在計算階乘的時候這些倍數都會算上)。如果n/p爲0,那麼不可能還會有p的倍數向n!的分解貢獻冪次,想一想爲什麼?
然後計算p*p,則和上面描述的一樣,共有n/(p*p)個數對p的冪次貢獻了1。爲什麼不是2呢?這是因爲在計算n/p的時候已經計算過一遍了,所以不需要重複計算。
依次迭代,直到n/(p^k)爲0,關於p的冪次纔算計算完成。

那麼如何計算k呢,現在已經得到a和n!的分解了,如果n!可以整除a^k,那麼a的所有質因子都可以在n!中找到,並且k爲相應冪次的倍數。

n!=p1e1 *p2e2 ··· piei ···
a==p1ee1 *p2ee2 ··· pieei ···

則e1>=k*ee1 ,e2>=k*ee2 ……
找出其中最小的倍數k即可。

#include <iostream>
#include <queue>
#include <stdlib.h>
#include <stdio.h>
#include <map>
#include <string>
#include <cstdlib>
#include <stack>
#include <vector>
#include <math.h>
#include <algorithm>
#include <typeinfo>
#include <cstring>


using namespace std;
typedef long long ll;

const int maxn = 1000004;
int prime[maxn];

std::vector<int> prm;


int fpow(int base,int exp){
	int ans=1;
	while(exp){
		if(exp&1)	ans*=base;
		base*=base;
		exp>>=1;
	}
	return ans;
}

void cr(void){
	memset(prime,1,sizeof(prime));
	prime[0]=prime[1]=0;
	for(int i=2;i<maxn;i++){
		if(prime[i]){
			prm.push_back(i);
			for(int j=i*2;j<maxn;j+=i)
				prime[j]=0;
		}
	}
	return;
}


int a[1003],b[1003];

int main(int argc, char const *argv[])
{
	cr();
	ll n,aa;
	while(cin>>n>>aa){
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		int cnt;
		for(int i=2;i<=n;i++){
			cnt=0;
			if(prime[i]){
				int p=1;
				while(n/fpow(i,p)){
					cnt+=n/fpow(i,p);
					p++;
				}
				a[i]=cnt;
			}
		}
		int s=aa;

		for(int i=2;i<=s;i++){
			if(prime[i]){
				int cnt=0;
				while(aa%i==0){
					cnt++;
					aa/=i;
				}
				b[i]=cnt;
			}
		}

		/*for(int i=2;i<=s;i++)
			cout<<b[i]<<" ";
		cout<<endl;*/

		int mi=0x3f3f3f3f;
		for(int i=2;i<n;i++){
			if(b[i]){
				if(mi>a[i]/b[i])
					mi=a[i]/b[i];
			}
		}
		cout<<mi<<endl;
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章