• hiho一下 第144周(机会渺茫)解题报告及拓展


    题目1 : 机会渺茫

    时间限制: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<=106

    对于100%的数据,满足1<=N,M<=1012

    输出

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

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

    Solution:

    Way1:

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <stdbool.h>
      4 
      5 long ans=0,maxn,zhi[100000];
      6 
      7 void Get_Zhi()
      8 {
      9     long i,j;
     10     bool vis[maxn+1];
     11     for (i=2;i<=maxn;i++)
     12         vis[i]=true;
     13     for (i=2;i<=maxn;i++)
     14     {
     15         if (vis[i])
     16         {
     17             ans++;
     18             zhi[ans]=i;
     19         }
     20         for (j=1;j<=ans;j++)
     21         {
     22             if (i*zhi[j]>maxn)
     23                 break;
     24             vis[i*zhi[j]]=false;
     25             if (i%zhi[j]==0)
     26                 break;
     27         }
     28     }
     29 }
     30 
     31 int main()
     32 {
     33     long long n,m,a,b,temp,x,y;
     34     long i,g;
     35     scanf("%lld%lld",&n,&m);
     36     if (n>m)
     37         maxn=(long)sqrt(n);
     38     else
     39         maxn=(long)sqrt(m);
     40     Get_Zhi();
     41     if (n>m)
     42     {
     43         a=n;
     44         b=m;
     45     }
     46     else
     47     {
     48         a=m;
     49         b=n;
     50     }
     51     while (b)
     52     {
     53         temp=b;
     54         b=a%b;
     55         a=temp;
     56     }
     57     x=1;
     58     y=1;
     59     //a
     60     if (a!=1)
     61     {
     62         for (i=1;i<=ans;i++)
     63             if (a%zhi[i]==0)
     64             {
     65                 g=1;
     66                 while (a%zhi[i]==0)
     67                 {
     68                     a/=zhi[i];
     69                     g++;
     70                 }
     71                 x*=g;
     72                 if (a==1)
     73                     break;
     74             }
     75         //a,n,m都有该质数,且系数都为1(若系数大于1,则相乘大于最大值)
     76         if (a!=1)
     77         {
     78             //x*2,y*4->x,y*2
     79             y*=2;
     80             n/=a;
     81             m/=a;
     82         }
     83     }
     84 
     85     //n
     86     if (n!=1)
     87     {
     88         for (i=1;i<=ans;i++)
     89             if (n%zhi[i]==0)
     90             {
     91                 g=1;
     92                 while (n%zhi[i]==0)
     93                 {
     94                     n/=zhi[i];
     95                     g++;
     96                 }
     97                 y*=g;
     98                 if (n==1)
     99                     break;
    100             }
    101         if (n!=1)
    102             y*=2;
    103     }
    104 
    105     //m
    106     if (m!=1)
    107     {
    108         for (i=1;i<=ans;i++)
    109             if (m%zhi[i]==0)
    110             {
    111                 g=1;
    112                 while (m%zhi[i]==0)
    113                 {
    114                     m/=zhi[i];
    115                     g++;
    116                 }
    117                 y*=g;
    118                 if (m==1)
    119                     break;
    120             }
    121         if (m!=1)
    122             y*=2;
    123     }
    124 
    125     a=y;
    126     b=x;
    127     while (b)
    128     {
    129         temp=b;
    130         b=a%b;
    131         a=temp;
    132     }
    133     x/=a;
    134     y/=a;
    135     printf("%lld %lld
    ",y,x);
    136     return 0;
    137 }

    Way2:

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <stdbool.h>
      4 
      5 long ans=0,maxn,zhi[100000];
      6 
      7 //打质数表!
      8 
      9 void Get_Zhi()
     10 {
     11     long i,j;
     12     bool vis[maxn+1];
     13     for (i=2;i<=maxn;i++)
     14         vis[i]=true;
     15     for (i=2;i<=maxn;i++)
     16     {
     17         if (vis[i])
     18         {
     19             ans++;
     20             zhi[ans]=i;
     21         }
     22         for (j=1;j<=ans;j++)
     23         {
     24             if (i*zhi[j]>maxn)
     25                 break;
     26             vis[i*zhi[j]]=false;
     27             if (i%zhi[j]==0)
     28                 break;
     29         }
     30     }
     31 }
     32 
     33 int main()
     34 {
     35     long long n,m,y=1;
     36     long i,j,g1=0,g2=0,p[100],q[100],u[100],v[100];
     37     scanf("%lld%lld",&n,&m);
     38     if (n>m)
     39         maxn=(long)sqrt(n);
     40     else
     41         maxn=(long)sqrt(m);
     42     Get_Zhi();
     43 
     44     //n
     45     if (n!=1)
     46     {
     47         for (i=1;i<=ans;i++)
     48             if (n%zhi[i]==0)
     49             {
     50                 g1++;
     51                 p[g1]=i;
     52                 q[g1]=1;
     53                 while (n%zhi[i]==0)
     54                 {
     55                     n=n/zhi[i];
     56                     q[g1]++;
     57                 }
     58                 if (n==1)
     59                     break;
     60             }
     61     }
     62     if (n!=1)
     63         y*=2;
     64 
     65     //m
     66     if (m!=1)
     67     {
     68         for (i=1;i<=ans;i++)
     69             if (m%zhi[i]==0)
     70             {
     71                 g2++;
     72                 u[g2]=i;
     73                 v[g2]=1;
     74                 while (m%zhi[i]==0)
     75                 {
     76                     m/=zhi[i];
     77                     v[g2]++;
     78                 }
     79                 if (m==1)
     80                     break;
     81             }
     82     }
     83     if (m!=1 && m!=n)
     84         y*=2;
     85     i=1;
     86     j=1;
     87     while (i<=g1 && j<=g2)
     88     {
     89         if (p[i]<u[j])
     90         {
     91             y*=q[i];
     92             i++;
     93         }
     94         else if (u[j]<p[i])
     95         {
     96             y*=v[j];
     97             j++;
     98         }
     99         else
    100         {
    101             if (q[i]>v[j])
    102                 y*=q[i];
    103             else
    104                 y*=v[j];
    105             i++;
    106             j++;
    107         }
    108     }
    109     while (i<=g1)
    110     {
    111         y*=q[i];
    112         i++;
    113     }
    114     while (j<=g2)
    115     {
    116         y*=v[j];
    117         j++;
    118     }
    119     printf("%lld 1
    ",y);
    120     return 0;
    121 }

    Way3:

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <stdbool.h>
      4 
      5 long ans=0,maxn,zhi[100000];
      6 
      7 void Get_Zhi()
      8 {
      9     long i,j;
     10     bool vis[maxn+1];
     11     for (i=1;i<=maxn;i++)
     12         vis[i]=true;
     13     for (i=2;i<=maxn;i++)
     14     {
     15         if (vis[i])
     16         {
     17             ans++;
     18             zhi[ans]=i;
     19         }
     20         for (j=1;j<=ans;j++)
     21         {
     22             if (i*zhi[j]>maxn)
     23                 break;
     24             vis[i*zhi[j]]=false;
     25             if (i%zhi[j]==0)
     26                 break;
     27         }
     28     }
     29 }
     30 
     31 int main()
     32 {
     33     long long n,m,a,b,temp,x,y;
     34     long g,i,r=0,t,p[100],q[100];
     35     scanf("%lld%lld",&n,&m);
     36     if (n>m)
     37         maxn=(long)sqrt(n);
     38     else
     39         maxn=(long)sqrt(m);
     40     Get_Zhi();
     41     if (n>m)
     42     {
     43         a=n;
     44         b=m;
     45     }
     46     else
     47     {
     48         a=m;
     49         b=n;
     50     }
     51     while (b)
     52     {
     53         temp=b;
     54         b=a%b;
     55         a=temp;
     56     }
     57     x=1;
     58     y=1;
     59 
     60     n/=a;
     61     m/=a;
     62 
     63     //a
     64     r=0;
     65     if (a!=1)
     66     {
     67     for (i=1;i<=ans;i++)
     68         if (a%zhi[i]==0)
     69         {
     70             r++;
     71             p[r]=i;
     72             q[r]=1;
     73             while (a%zhi[i]==0)
     74             {
     75                 a/=zhi[i];
     76                 q[r]++;
     77             }
     78             x*=q[r];
     79             if (a==1)
     80                 break;
     81         }
     82         //a,n,m都有该质数,且系数都为1(若系数大于1,则相乘大于最大值)
     83         //x*2,y*4->x,y*2
     84         if (a!=1)
     85             y*=2;
     86     }
     87     p[r+1]=1000000;
     88 
     89     //n
     90     if (n!=1)
     91     {
     92         t=1;
     93         for (i=1;i<=ans;i++)
     94             if (n%zhi[i]==0)
     95             {
     96                 g=1;
     97                 while (n%zhi[i]==0)
     98                 {
     99                     n/=zhi[i];
    100                     g++;
    101                 }
    102                 //p[r+1]=1000000;
    103                 while (p[t]<i)
    104                 {
    105                     y*=q[t];
    106                     t++;
    107                 }
    108                 if (p[t]==i)
    109                 {
    110                     y*=(g+q[t]-1);
    111                     t++;
    112                 }
    113                 else
    114                     y*=g;
    115                 if (n==1)
    116                     break;
    117             }
    118         if (n!=1)
    119             y*=2;
    120         while (t<=r)
    121         {
    122             y*=q[t];
    123             t++;
    124         }
    125     }
    126     else
    127         y*=x;
    128 
    129     //m
    130     if (m!=1)
    131     {
    132         t=1;
    133         for (i=1;i<=ans;i++)
    134             if (m%zhi[i]==0)
    135             {
    136                 g=1;
    137                 while (m%zhi[i]==0)
    138                 {
    139                     m/=zhi[i];
    140                     g++;
    141                 }
    142                 //p[r+1]=1000000;
    143                 while (p[t]<i)
    144                 {
    145                     y*=q[t];
    146                     t++;
    147                 }
    148                 if (p[t]==i)
    149                 {
    150                     y*=(g+q[t]-1);
    151                     t++;
    152                 }
    153                 else
    154                     y*=g;
    155                 if (m==1)
    156                     break;
    157             }
    158         if (m!=1)
    159             y*=2;
    160         while (t<=r)
    161         {
    162             y*=q[t];
    163             t++;
    164         }
    165     }
    166     else
    167         y*=x;
    168 
    169     a=y;
    170     b=x;
    171     while (b)
    172     {
    173         temp=b;
    174         b=a%b;
    175         a=temp;
    176     }
    177     x/=a;
    178     y/=a;
    179     printf("%lld %lld
    ",y,x);
    180     return 0;
    181 }
    182 /*
    183 input:
    184 16 8
    185 output:
    186 5 1
    187 
    188 input:
    189 60 48
    190 output:
    191 20 1
    192 */

    Advance:

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <stdbool.h>
     4 #define maxn 100000
     5 #define maxs 100000
     6 
     7 long zhi[maxn],z[maxs+1][12],g[maxs+1][12],ansz[maxs+1];
     8 
     9 void Get_Zhi()
    10 {
    11     long i,j,s,ans=0;
    12     long long k;
    13     bool vis[maxn+1];
    14     for (i=2;i<=maxn;i++)
    15         vis[i]=true;
    16     for (i=2;i<=maxn;i++)
    17     {
    18         if (vis[i])
    19         {
    20             ans++;
    21             zhi[ans]=i;
    22             for (j=i;j<=maxs;j+=i)
    23             {
    24                 ansz[j]++;
    25                 z[j][ansz[j]]=i;
    26                 //为了求约数总数,比正确个数多1
    27                 g[j][ansz[j]]=2;
    28             }
    29             k=(long long)i*i;
    30             s=2;
    31             while (k<=maxs)
    32             {
    33                 for (j=k;j<=maxs;j+=k)
    34                     g[j][ansz[j]]++;
    35                 k=(long long)k*i;
    36                 s++;
    37             }
    38         }
    39         for (j=1;j<=ans;j++)
    40         {
    41             if (i*zhi[j]>maxn)
    42                 break;
    43             vis[i*zhi[j]]=false;
    44             if (i%zhi[j]==0)
    45                 break;
    46         }
    47     }
    48 }
    49 
    50 int main()
    51 {
    52     long i,j,m,n;
    53     double result=0,re;
    54     for (i=1;i<=maxs;i++)
    55         ansz[i]=0;
    56     Get_Zhi();
    57     for (n=1;n<=maxs;n++)
    58         for (m=1;m<=maxs;m++)
    59         {
    60             re=1.0;
    61             i=1;
    62             j=1;
    63             while (i<=ansz[n] && j<=ansz[m])
    64             {
    65                 if (z[n][i]<z[m][j])
    66                 {
    67                     re/=g[n][i];
    68                     i++;
    69                 }
    70                 else if (z[n][i]>z[m][j])
    71                 {
    72                     re/=g[m][j];
    73                     j++;
    74                 }
    75                 else
    76                 {
    77                     if (g[n][i]>g[m][j])
    78                         re/=g[n][i];
    79                     else
    80                         re/=g[m][j];
    81                     i++;
    82                     j++;
    83                 }
    84             }
    85             while (i<=ansz[n])
    86             {
    87                 re/=g[n][i];
    88                 i++;
    89             }
    90             while (j<=ansz[m])
    91             {
    92                 re/=g[m][j];
    93                 j++;
    94             }
    95             result+=re;
    96         }
    97     printf("%lf
    ",result*1.0/maxs/maxs);
    98     return 0;
    99 }
  • 相关阅读:
    flash 显示对象的getRect()方法的问题
    John Maccarthy
    一个c++ 2d图形引擎 AGG
    lisp 编程入门
    linux图形开发工具
    wxDevC++ – Dev C++的愛好者一定要知道的C++ IDE
    备忘 html5 canvas context2d/3d
    windows下使用boost库可以下载编译好的二进制安装包
    酷壳
    [.NET] : Provider Pattern
  • 原文地址:https://www.cnblogs.com/cmyg/p/6683179.html
Copyright © 2020-2023  润新知