【九度OJ】题目1104:整除问题

http://ac.jobdu.com/problem.php?pid=1104


参考了:

1.http://blog.csdn.net/jdplus/article/details/19413037

2.http://blog.csdn.net/jaster_wisdom/article/details/52144308


有两种做法:

第一种做法,把n!做素数分解,用cnt1[i]代表n!中含有的primes[i]的因子个数:如果n/primes[i] == x, 那么在n!中就有x个数含有primes[i]为它的因子,但是这x个数中有的数含有多个primes[i]为它的因子,所以还需要不断的做 cnt1[i] += x/primes[i], x= x/primes[i],直到x == 0。

具体对应代码:

[cpp]  view plain  copy
  1. while(t){  
  2.     cnt1[i] += t/primes[i];  
  3.     t= t/primes[i];  
  4. }  

用cnt2[i] 代表a中含有primes[i]的因子个数。

扫描二维码关注公众号,回复: 941750 查看本文章


k值为cnt1[i]/cnt2[i]的最大值。

[cpp]  view plain  copy
  1. #include <stdio.h>  
  2. #include <algorithm>  
  3.   
  4. using namespace std;  
  5. int primes[1001];  
  6. int primeNum;  
  7. bool temp[1001];  
  8.   
  9. void init(){  
  10.     for(int i =0; i<=1000;i++){  
  11.         temp[i] = true;  
  12.     }  
  13.     for(int i =2; i<=1000;i++){  
  14.         if(!temp[i]) continue;  
  15.         for(int j = i*i ;j<=1000;j+=i){  
  16.             temp[j] = false;  
  17.         }  
  18.     }  
  19.     primeNum = 0;  
  20.     for(int i=2;i<=1000;i++){  
  21.         if(temp[i]){  
  22.             primes[primeNum++] = i;  
  23.         }  
  24.     }  
  25. }  
  26.   
  27. int main(int argc, char* argv[])  
  28. {  
  29.     init();  
  30.     int cnt1[1001],cnt2[1001];  
  31.     int a,n;  
  32.     int ans;  
  33.     while(scanf("%d %d" ,&n,&a)!=EOF){  
  34.         for(int i=0; i<=1000;i++){  
  35.             cnt1[i] = cnt2[i] = 0;  
  36.         }  
  37.         ans = 0x7fffff;  
  38.         for(int i=0;i<primeNum;i++){  
  39.             int t = n;  
  40.             while(t){  
  41.                 cnt1[i] += t/primes[i];  
  42.                 t= t/primes[i];  
  43.             }  
  44.   
  45.             while(a%primes[i] ==0){  
  46.                 cnt2[i]++;  
  47.                 a=a/primes[i];  
  48.             }  
  49.             if(cnt2[i] == 0) continue;  
  50.             if(cnt1[i]/cnt2[i] < ans){  
  51.                 ans = cnt1[i]/cnt2[i];  
  52.             }  
  53.         }  
  54.         printf("%d\n",ans);  
  55.     }  
  56.     return 0;  
  57. }  




第二种做法是:

在算n!的时候同时算出k,因为只要factor %a ==0 那么factor=factor/a, k++; 又因为当factor不可以%a==0 时, factor = ma + x。 其中ma是肯定可以被a整除的,i*ma也会被a整除,所以在继续算factor时ma部分不会影响factor%a=0, 所以可以将这部分舍掉,factor = factor%a。

[cpp]  view plain  copy
  1. #include <stdio.h>  
  2.   
  3. int main(){   
  4.     int n,a,k;   
  5.     long long factor;  
  6.     while(scanf("%d %d",&n,&a) !=EOF){   
  7.         factor = 1;   
  8.         k = 0;  
  9.         for (int i = 1; i <=n; ++i) {   
  10.             factor *= i;   
  11.             while(factor%a==0){   
  12.                 k++;   
  13.                 factor /= a;  
  14.             }    
  15.             //factor = ma + x, ma will not help to increase k  
  16.             //delete ma to prevent overflow   
  17.             factor = factor % a;  
  18.         }   
  19.         printf("%d\n",k);   
  20.     }    
  21. }    

猜你喜欢

转载自blog.csdn.net/qq_34898866/article/details/80210691