zoukankan      html  css  js  c++  java
  • 细胞*【唯一分解定理】

    题目链接:https://ac.nowcoder.com/acm/contest/1106/B

    题目大意:

    1.依次给出n,m1,m2,si。m1的m2次方代表一个值A,求在n个si中,各个si的x次方是A的倍数,x的最小值。

    题解思路:

    1.对m1进行质因数分解,得到每个质因子的次方,次方乘个m2即得到m1^m2的质因数分解结果。

    2.枚举si,对于每一个si,若其没有包含m1^m2所有的质因数,则任si次方增长也无法达到m1^m2的倍数。若包含了m1^m2的所有质因数,则只需要求这些质因数 在m1^m2中的次方比上在si中的次方,向上取整,取其中的最大值。(意为si达到m1 ^m2的倍数至少需要增加的次方数)。结果是对于每一个si的结果取最小值。

    代码如下:

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<math.h>
     4 #include<algorithm>
     5 #define mem(a, b) memset(a, b, sizeof(a))
     6 const int inf = 0x3f3f3f3f;
     7 using namespace std;
     8 
     9 int n, m1, m2, cnt;
    10 int s[10010], vis[30010], a[30010], b[30010]; //a存质因子,b存该质因子的次数 
    11 int prime[30010];
    12 
    13 void get_prime(int n)  //得到2~m1范围内所有的素数 
    14 {
    15     mem(vis, 1), cnt = 0;
    16     for(int i = 2; i <= n; i ++)
    17     {
    18         if(vis[i])
    19         {
    20             prime[++ cnt] = i;
    21             for(int j = i; j <= n; j += i)
    22                 vis[j] = 0;
    23         }
    24     }
    25 }
    26 
    27 int main()
    28 {
    29     int n;
    30     scanf("%d%d%d", &n, &m1, &m2);
    31     for(int i = 1; i <= n; i ++)
    32         scanf("%d", &s[i]);
    33     if(m1 == 1)
    34         printf("0
    ");
    35     else
    36     {
    37         get_prime(m1);
    38         int x = m1, k = 0; //k是质因子数量 
    39         for(int i = 1; i <= cnt; i ++)
    40         {
    41             if(x % prime[i] == 0)
    42             {
    43                 k ++;
    44                 a[k] = prime[i];
    45                 int p = 0;  //该质因子次数 
    46                 while(x % prime[i] == 0)
    47                 {
    48                     p ++;
    49                     x /= prime[i];
    50                 }
    51                 b[k] = p * m2;  //得到m1 ^ m2的所有质因数以及次方 
    52             }
    53             if(x == 1)
    54                 break;
    55         }
    56         int ans = inf;
    57         for(int i = 1; i <= n; i ++)
    58         {
    59             int maxx = 0;
    60             for(int j = 1; j <= k; j ++)
    61             {
    62                 if(s[i] % a[j]) //若s[i]没有包含m1 ^ m2的所有质因数,则去除掉 
    63                 {
    64                     maxx = inf;
    65                     break;
    66                 }
    67                 int p = 0, x = s[i];
    68                 while(x % a[j] == 0)
    69                 {
    70                     x /= a[j];
    71                     p ++;
    72                 }
    73                 int temp = ceil(b[j] * 1.0 / p); //注意向上取整时,转化成浮点型计算,否则整形/整形依然是整形,没有达到向上取整的作用 
    74                 maxx = max(maxx, temp);
    75             }
    76             ans = min(ans, maxx);
    77         }
    78         if(ans == inf)
    79             printf("-1
    ");
    80         else
    81             printf("%d
    ", ans);
    82     }
    83     return 0;
    84 }
    View Code

    扩展:

    该解法用于,求解一个数B的最小次方x是A的倍数,求x。(当A是m1^m2型很大的数据时,B的次方也很大时)。

  • 相关阅读:
    CSS 基础(一)
    74.Search a 2D Matrix
    73.Set Matrix Zeroes
    66.Plus One
    64.Minimum Path Sum
    63.Unique Paths II
    62.Unique Paths
    54.Spiral Matrix
    59.Spiral Matrix II
    55.Jump Game
  • 原文地址:https://www.cnblogs.com/yuanweidao/p/11748906.html
Copyright © 2011-2022 走看看