Hihocoder 1284 机会渺茫
2017-04-19 09:20
495 查看
机会渺茫
小Hi最近在追求一名学数学的女生小Z。小Z其实是想拒绝他的,但是找不到好的说辞,于是提出了这样的要求:对于给定的两个正整数N和M,小Hi随机选取一个N的约数N’,小Z随机选取一个M的约数M’,如果N’和M’相等,她就答应小Hi。小Z让小Hi去编写这个随机程序,到时候她review过没有问题了就可以抽签了。但是小Hi写着写着,却越来越觉得机会渺茫。那么问题来了,小Hi能够追到小Z的几率是多少呢?
Input
每个输入文件仅包含单组测试数据。
每组测试数据的第一行为两个正整数N和M,意义如前文所述。
对于40%的数据,满足1<=N,M<=106
对于100%的数据,满足1<=N,M<=1012
Output
对于每组测试数据,输出两个互质的正整数A和B(以A分之B表示小Hi能够追到小Z的几率)。
Sample Input
3 2
Sample Output
4 1
题目很简单呀,就是gcd的应用。
对于给定的两个数N、M,我们需要求出它们所有的公约数(分子);
还要求出所有的情况(nm因子个数相乘,分母)。
做法有两种:
第一种,我们将NM素因子分解(参见唯一分解定理),然后得到
N=a1^k1 * a2^k2 * a3^k3 ……;M=b1^p1 * b2^p2 *b2^k3……;
相同因子个数:跑一遍map,对于每个相同的因子same*=min(pfn[i]+1,pfm(i)+1);(事实证明单纯这样做是有问题的,对于NM为质数的时候,e.g. 5 5 ans应该是2/1,而我写的算出来是4/1,尴尬了,说明测试数据水,我是要被hack的)
第二种,其实相同的因子个数就是gcd(N,M)的所有因子的个数,求可以直接分解,也可以素因子分解,没关系的;
相对应的N,M的分解也要对应gcd(N,M)的分解方式,用同一种方法。
代码如下:
//AC(水过了,求大佬解释) #include<cstdio> #include<iostream> using namespace std; typedef long long ll; ll gcd(ll a,ll b){ return b==0?a:gcd(b,a%b); } map<ll,ll>pfn; map<ll,ll>pfm; /* ll prime_factor(ll p,map<ll,ll>&pf){ ll cnt=0; for(ll i=2;i*i<=p;i++){//n为素数 while(p%i==0){ ++pf[i]; p/=i; cnt++; } } if(p!=1)pf[p]=1;cnt++; return cnt; }*/ int main(){ ll n,m,nn,mm,cntn=1,cntm=1; cin>>n>>m; nn=n;mm=m; for(ll i=2;i*i<=n;i++){ while(n%i==0){ ++pfn[i]; n/=i; } cntn*=(pfn[i]+1); } if(n!=1){pfn =1;cntn*=(pfn +1);} for(ll i=2;i*i<=m;i++){ while(m%i==0){ ++pfm[i]; m/=i; } cntm*=(pfm[i]+1); } if(m!=1){pfm[m]=1;cntm*=(pfm[m]+1);} ll tol=cntn*cntm; ll sum=1; for(ll i=2;i*i<=max(nn,mm);i++){/attention!!!!! //if(pfn.count(i)&&pfm.count(i)){ if(pfn[i]&&pfm[i]){ sum*=min(pfn[i]+1,pfm[i]+1); } } ll gcdmax=gcd(tol,sum); cout<<tol/gcdmax<<" "<<sum/gcdmax<<endl; return 0; }
第二种
//简单的解法(上面是素因子,这个是直接求因子,不是素的) #include<cstdio> #include<iostream> using namespace std; long long gcd(long long x,long long y){ return y==0?x:gcd(y,x%y); } long long num(long long s){ long long a=0; long long i; for (i=1; i<=s/i; i++){ if (s%i==0) a++; else continue; if (s/i!=i) a++; } return a; } int main(){ long long n,m,x,y,z,cnt; scanf ("%lld %lld",&n,&m); long long p=gcd(n,m); x=num(p); y=num(n); z=num(m); cnt=y*z; z=gcd(x,cnt); printf("%lld %lld\n",cnt/z,x/z); return 0; }
等会二我再来补第一种的完美AC的代码,要跑一个map;
相关文章推荐
- HihoCoder - 1284 机会渺茫
- hihocoder-1284 机会渺茫(水题)
- 【HihoCoder】1284 - 机会渺茫(STL - set)
- hihoCoder1284机会渺茫(唯一分解定理 + 约分)
- 【hihoCoder 1284 机会渺茫】
- hihocoder-1284-机会渺茫【map】【set】
- hihocoder 1284 (机会渺茫)
- Hihocoder-----1284---机会渺茫
- hihocoder 1284 机会渺茫(GCD+思维)
- hihoCoder - 1284 机会渺茫
- hihocoder 机会渺茫
- 【hihocoder】机会渺茫
- hihoCoder | hiho一下144周 机会渺茫
- hihocoder#1284 : 机会渺茫
- hihoCoder-week144:机会渺茫
- 【hihoCode】-1284-机会渺茫(STL-set)
- HihoCode 1284 : 机会渺茫【约数个数】
- hihoCoder #1284 : 机会渺茫
- hihoCoder #1284 : 机会渺茫(思维,数学)
- 【hihocoder】机会渺茫(map,离散化,概率计算,gcd)