poj 2649 Factovisors

本文介绍了一个用于判断两个整数间整除关系的C++程序。该程序通过质因数分解来确定较小数是否能整除较大数,并采用筛法预先计算一定范围内的所有质数。

  继续做一下分解质因数的水题!

 

View Code
  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <cmath>
  5 #include <algorithm>
  6 #include <iostream>
  7 
  8 #define debug 0
  9 
 10 using namespace std;
 11 
 12 typedef __int64 ll;
 13 const int maxn = 100005;
 14 
 15 bool np[maxn];
 16 int pn, pr[maxn >> 2];
 17 
 18 void gp(){
 19     memset(np, 0, sizeof(np));
 20     np[0] = np[1] = true;
 21     pn = 0;
 22     for (int i = 2; i < maxn; i++){
 23         if (!np[i]) pr[pn++] = i;
 24         for (int j = 0; j < pn && pr[j] * i < maxn; j++){
 25             np[pr[j] * i] = true;
 26             if (i % pr[j] == 0) break;
 27         }
 28     }
 29     #if debug
 30     printf("pn %d\n", pn);
 31     #endif
 32 }
 33 
 34 void fac(int a, int *f, int *n, int &cnt){
 35     int i = 0;
 36 
 37     cnt = 0;
 38     if (!a) return ;
 39     while (pr[i] * pr[i] <= a && i < pn){
 40         if (a % pr[i] == 0){
 41             f[cnt] = pr[i];
 42             n[cnt] = 0;
 43             while (a % pr[i] == 0) a /= pr[i], n[cnt]++;
 44             cnt++;
 45         }
 46         i++;
 47     }
 48     if (a != 1) f[cnt] = a, n[cnt++] = 1;
 49 }
 50 
 51 int cnt_fac(int n, int f){
 52     int ep = f;
 53     int ret = 0;
 54 
 55     while (ep <= n){
 56         ret += n / ep;
 57         ep *= f;
 58     }
 59 
 60     return ret;
 61 }
 62 
 63 bool deal(int a, int b){
 64     int f[30], cf[30];
 65     int n = 0;
 66 
 67     memset(f, 0, sizeof(f));
 68     fac(a, f, cf, n);
 69     #if debug
 70     printf("n  %d\n\n", n);
 71     for (int i = 0; i < n; i++) {
 72         printf("%d  %d\n", f[i], cf[i]);
 73     }
 74     f[n] = 0;
 75     #endif
 76 
 77     for (int i = 0; i < n; i++) {
 78         #if debug
 79         printf("fac %d  num %d\n", f[i], cnt_fac(b, f[i]));
 80         #endif
 81         if (cf[i] > cnt_fac(b, f[i])) {
 82             return false;
 83         }
 84     }
 85     return true;
 86 }
 87 
 88 int main(){
 89     int a, b;
 90 
 91     gp();
 92     while (~scanf("%d%d", &a, &b)){
 93         if (deal(b, a) && b) {
 94             printf("%d divides %d!\n", b, a);
 95         }
 96         else {
 97             printf("%d does not divide %d!\n", b, a);
 98         }
 99     }
100 
101     return 0;
102 }

 

——written by Lyon

转载于:https://www.cnblogs.com/LyonLys/archive/2012/08/05/poj_2649_Lyon.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值