zoukankan      html  css  js  c++  java
  • noip2009提高组第二题、vijos p 1753——HankSon的趣味题

    描述

    Hanks 博士是 BT (Bio-Tech,生物技术) 领域的知名专家,他的儿子名叫 Hankson。现
    在,刚刚放学回家的 Hankson 正在思考一个有趣的问题。
    今天在课堂上,老师讲解了如何求两个正整数 c1和 c2 的最大公约数和最小公倍数。现
    在 Hankson 认为自己已经熟练地掌握了这些知识,他开始思考一个“求公约数”和“求公
    倍数”之类问题的“逆问题” ,这个问题是这样的:已知正整数 a0,a1,b0,b1,设某未知正整
    数 x 满足:
    1. x 和 a0 的最大公约数是 a1;
    2. x 和b0 的最小公倍数是 b1。
    Hankson 的“逆问题”就是求出满足条件的正整数 x。但稍加思索之后,他发现这样的
    x 并不唯一,甚至可能不存在。因此他转而开始考虑如何求解满足条件的 x 的个数。请你帮
    助他编程求解这个问题。

    格式

    输入格式

    第一行为一个正整数 n,表示有 n 组输入数据。接下来的 n 行每
    行一组输入数据,为四个正整数 a0,a1,b0,b1,每两个整数之间用一个空格隔开。输入
    数据保证 a0能被 a1 整除,b1 能被 b0整除。

    输出格式

    共n 行。每组输入数据的输出结果占一行,为一个整数。
    对于每组数据:若不存在这样的 x,请输出 0;
    若存在这样的 x,请输出满足条件的 x 的个数;

    样例1

    样例输入1[复制]

     
    2 
    41 1 96 288 
    95 1 37 1776 

    样例输出1[复制]

     
    6 
    2 

    限制

    每个测试点1s

    先分解b1的质因数,因为按理说b1是大于等于a1和b0的,那么正常情况下a1的质因数和b0的质因数是包含在内的。

    于是开始找。用b1.c[i]、b0.c[i]、a0.c[i]、a0.c[i]表示前面那个数的质因数数组(这里4个应该是一样的)_.len[i]表示前面那个数的当前质因数个数

    怎么找质因数?定义x=2,用while循环和x++即可。

    接下来就是处理。我们可以想到,枚举第i个质因数时,若b1含的指数是大于b0的,那么x只能为b1的那个指数。原因:若x比b1指数小,则最小公倍数为x或者b0,而非b1。若x比b1指数大,则最小公倍数为x。因此此时x取指数只能为唯一情况。同理,若a0的指数大于a1,则x只能为a1的那个指数,解释方法相同。那么这两种情况同时存在呢?这个时候,x的2个取值b1.num[i]!=a1.num[i],则与题意矛盾,这组数据无解。当然,若b1.num[i]<a1.num[i]也是无解,因为这是不可能存在的。

    最后的最后,若b1.num[i]=b0.num[i]&&a1.num[i]==a0.num[i],则x能取的指数个数则为两个个数中间的那个区间。这样就求出了x在各个质数能取的情况,最后用乘法原理乘起来就得到了ans         ~(≧▽≦)/~啦啦啦!

    代码:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int n,ans=0;int p=1;
    struct node{
    int la,c[2005],num[2005],tot;
    }a0,a1,b0,b1;
    int l[2005],r[2005];
    int main()
    {
      freopen("son.in","r",stdin);
      freopen("son.out","w",stdout);
      scanf("%d",&n);//cin>>n;//数据数
      while(n>0)
      {
        n--;p=1;
        scanf("%d %d %d %d",&a0.la,&a1.la,&b0.la,&b1.la);//cin>>a0.la>>a1.la>>b0.la>>b1.la;
        int x=2;b1.tot=0;
        while(b1.la>=x*x)//分解质因数
        {
          int len=0;
          while(b1.la%x==0)
          {
            len++;
            b1.la/=x;
          }
          if(len>0)
          {
            b1.c[++b1.tot]=x;
            b1.num[b1.tot]=len;
          }
          x++;
        }
        if(b1.la!=1)//分解质因数
        {
          b1.c[++b1.tot]=b1.la;
          b1.num[b1.tot]=1;
        }
        for(int i=1;i<=b1.tot;i++)
        {
          int len=0;a0.c[i]=b1.c[i];
          while(a0.la%b1.c[i]==0)
          {
            len++;
            a0.la/=b1.c[i];
          }
          a0.num[i]=len;
        }
        for(int i=1;i<=b1.tot;i++)
        {
          int len=0;a1.c[i]=b1.c[i];
          while(a1.la%b1.c[i]==0)
          {
            len++;
            a1.la/=b1.c[i];
          }
          a1.num[i]=len;
        }
        for(int i=1;i<=b1.tot;++i)
        {
          int len=0;b0.c[i]=b1.c[i];
          while(b0.la%b1.c[i]==0)
          {
            len++;
            b0.la/=b1.c[i];
          }
          b0.num[i]=len;
        }
        for(int i=1;i<=b1.tot;++i)
        {
          if(b1.num[i]<a1.num[i]) //不符
          {
            p=0;
            break;
          }
          if(a1.num[i]!=a0.num[i]&&b1.num[i]>a1.num[i]&&b1.num[i]!=b0.num[i])//不符
          {
            p=0;
            break;
          }
          if(a1.num[i]!=a0.num[i])
          {
            l[i]=a1.num[i];
            r[i]=a1.num[i];
            continue;
          }
          if(b1.num[i]!=b0.num[i])
          {
            l[i]=b1.num[i];
            r[i]=b1.num[i];
            continue;
          }
          l[i]=a1.num[i];r[i]=b1.num[i];//若都等于
        }
        ans=1;
        for(int i=1;i<=b1.tot;i++)
        ans*=(r[i]-l[i]+1);
        if(p==0)ans=0;
        printf("%d ",ans);//cout<<ans<<endl;
      }
      return 0;
    }

  • 相关阅读:
    【POJ】[1703]Find them, Catch them
    【杭电】[2717]Catch That Cow
    【杭电】[2717]Catch That Cow
    【杭电】[1716]排列2
    【杭电】[1716]排列2
    【杭电】[2084]数塔
    【杭电】[2084]数塔
    【杭电】[1003]Max Sum
    【杭电】[1003]Max Sum
    [leetcode]117. Populating Next Right Pointers in Each NodeII用next填充同层相邻节点
  • 原文地址:https://www.cnblogs.com/937337156Zhang/p/5823537.html
Copyright © 2011-2022 走看看