zoukankan      html  css  js  c++  java
  • hihoCoder1284机会渺茫(唯一分解定理 + 约分)

    题目链接

    #1284 : 机会渺茫

    时间限制:5000ms
    单点时限:1000ms
    内存限制:256MB

    描述

    小Hi最近在追求一名学数学的女生小Z。小Z其实是想拒绝他的,但是找不到好的说辞,于是提出了这样的要求:对于给定的两个正整数N和M,小Hi随机选取一个N的约数N',小Z随机选取一个M的约数M',如果N'和M'相等,她就答应小Hi。

    小Z让小Hi去编写这个随机程序,到时候她review过没有问题了就可以抽签了。但是小Hi写着写着,却越来越觉得机会渺茫。那么问题来了,小Hi能够追到小Z的几率是多少呢?

    输入

    每个输入文件仅包含单组测试数据。

    每组测试数据的第一行为两个正整数N和M,意义如前文所述。

    对于40%的数据,满足1<=N,M<=10^6

    对于100%的数据,满足1<=N,M<=10^12

    输出

    对于每组测试数据,输出两个互质的正整数A和B(以A分之B表示小Hi能够追到小Z的几率)。

    样例输入
    3 2
    样例输出
    4 1

    分析:对 n 和 m 分解,得到n和m的每一个素数的指数en[],em[],然后取公约数,即取每个指数小的那个得到新的 et[], sum(et[]) / sum(en[]) * sum(em[])即所求,就是在en里面找一个,在em里面找一个,1/(sum[en] * sum[em]),一共有sum[et]个
    题目等级为2,然后我却WA了好几次,RE了好几次 =_=...
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 using namespace std;
     5 typedef long long LL;
     6 const int Max = 10000000 + 5; //开到6次RE
     7 bool flag[Max + 5];
     8 int prime[Max + 5], tot;
     9 int en[Max + 5], em[Max + 5], et[Max + 5];
    10 void get_prime()
    11 {
    12     memset(flag, false, sizeof(flag));
    13     tot = 0;
    14     for (int i = 2; i <= Max;i ++)
    15     {
    16         if (!flag[i])
    17         {
    18             prime[++tot] = i;
    19             for (int j = i; j <= Max / i; j++)
    20                 flag[i * j] = true;
    21         }
    22     }
    23 }
    24 void get_fact(LL n, int * temp)
    25 {
    26     memset(temp, 0, sizeof(temp));
    27     for (int i = 1; i <= tot; i++)
    28     {
    29         if (prime[i] > n)
    30             break;
    31         if (n % prime[i] == 0)
    32         {
    33             while (n % prime[i] == 0)
    34             {
    35                 n = n / prime[i];
    36                 temp[prime[i]]++;
    37             }
    38         }
    39     }
    40     if (n > 1)
    41         temp[n]++;
    42 }
    43 LL get_sum(int temp[])
    44 {
    45     LL sum = 1;
    46     for (int i = 1; i <= tot; i++)
    47     {
    48         if (temp[prime[i]])
    49             sum *= (temp[prime[i]] + 1);
    50     }
    51     return sum;
    52 }
    53 void solve()
    54 {
    55     memset(et, 0, sizeof(et));
    56     for (int i = 1; i <= tot; i++)
    57     {
    58         if (en[prime[i]] && em[prime[i]])
    59         {
    60             int minn = min (en[prime[i]], em[prime[i]]);  //取最小的指数
    61             et[prime[i]] += minn;
    62         }
    63     }
    64 }
    65 LL get_gcd(LL a, LL b)
    66 {
    67     if (b == 0)
    68         return a;
    69     return get_gcd(b, a % b);
    70 }
    71 int main()
    72 {
    73     get_prime();
    74     LL n, m;
    75     scanf("%lld%lld", &n, &m);
    76     get_fact(n, en);
    77     get_fact(m, em);
    78     solve();
    79     LL numn = get_sum(en);
    80     LL numm = get_sum(em);
    81     LL numf = get_sum(et);
    82 
    83    // 最后结果就是 numf / (numn * numm)
    84    所以先对numf 和 numn约分,
    85   然后把约分后的numf与numm约分,最后numn * numm
    86     LL x1 = numf;
    87     LL t1 = get_gcd(numn, numf);
    88     x1 = x1 / t1;   
    89     numn = numn / t1;
    90 
    91     LL t2 = get_gcd(numm, x1);
    92     x1 = x1 / t2;
    93     numm = numm / t2;
    94     numn = numn * numm;
    95 
    96     printf("%lld %lld
    ", numn, x1);
    97     return 0;
    98 }
    View Code
  • 相关阅读:
    Qt共享内存实现进程间通信(QSharedMemory)
    Qt5.5制作简单的屏幕截图程序
    006--C++动态内存(简介)
    005--C++字符
    004--C++11的初始化方式
    003--sizeof的使用
    002--C++程序的创建
    001--基础知识准备
    Qt5.5连接MySQL
    vue-cli中如何创建并引入自定义组件
  • 原文地址:https://www.cnblogs.com/zhaopAC/p/5326429.html
Copyright © 2011-2022 走看看