BestCoder Round #60/HDU 5505 暴力数学

GT and numbers

 
问题描述
给出两个数NN和MM。 NN每次可以乘上一个自己的因数变成新的NN。 求最初的NN到MM至少需要几步。 如果永远也到不了输出-11。
输入描述
第一行读入一个数TT表示数据组数。 接下来TT行,每行两个数NN和MM。 T\leq1000T1000, 1\leq N \leq 10000001N1000000,1 \leq M \leq 2^{63}1M263​​. 注意M的范围。hack时建议输出最后一行的行末回车;每一行的结尾不要输出空格。
输出描述
对于每组数据,输出一个数表示答案。
输入样例
3
1 1
1 2
2 4
输出样例
0
-1
1

题解:对n质数分解成x个指数因子,再对m进行整除到底,知道所得m为1为止,记录步数ans就是答案,否则-1;
///1085422276
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<cmath>
#include<map>
#include<bitset>
#include<set>
#include<vector>
using namespace std ;
typedef unsigned long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,127,sizeof(a));
#define memfy(a)  memset(a,-1,sizeof(a));
#define TS printf("111111\n");
#define FOR(i,a,b) for( int i=a;i<=b;i++)
#define FORJ(i,a,b) for(int i=a;i>=b;i--)

#define inf 100000000
inline ll read()
{
    ll x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
//***************************************
#define maxn 1000000+5
  bool P[maxn];
  int k;
  int  prime[maxn];
  vector<int  >V;
  int H[maxn],S[maxn];
  void init()
  {
      P[1]=1;
    for(int i=1;i<=1000001;i++)
      {
          if(!P[i])
          {
              for(int j=i+i;j<=1000001;j=j+i)
                P[j]=1;
          }
      }
      k=0;
      for(int i=1;i<=1000001;i++)
      {
          if(!P[i])
             prime[++k]=i;
      }
  }
 __int64 get( __int64 x,__int64 y)
  {
      __int64 j=1;
      while(y<x)
      {
          x-=y;
          j++;
          y+=y;
      }
      if(j==0)j++;
      return j;
  }
  int main()
  {
      int T;
      init();
      scanf("%d",&T);

      while(T--)
      {
          V.clear();
          ll n=read();
          ll m=read();
          if(n==m)
          {
              printf("0\n");
              continue;
          }
          if(n>m)
          {
            printf("-1\n");
              continue;
          }
          if(n==1)
          {
             printf("-1\n");
              continue;
          }
          if(m%n){
            cout<<-1<<endl;
            continue;
          }
          ll tmp=m/n;//cout<<tmp<<endl;
         for(int i=1;i<=k;i++)
         {
             while(n%prime[i]==0)
             {
                 if(H[prime[i]]==0)
                 V.push_back(prime[i]);
                 H[prime[i]]++;
                 n/=prime[i];
             }if(prime[i]>n)break;
         } // for(int i=0;i<V.size();i++)cout<<V[i]<<endl;
        __int64  ans=0;
         for(int i=0;i<V.size();i++)
         {
             if(tmp%V[i]==0) {
                 ll jj=0;
                 while(tmp%V[i]==0)
                 {
                     tmp/=V[i];
                     jj++;
                 }
                ans=max(ans,get(jj,H[V[i]]));
             }
             H[V[i]]=0;
         }
         if(tmp!=1){
            printf("-1\n");
         }
         else printf("%I64d\n",ans);

      }

      return 0;
  }
代码

 

转载于:https://www.cnblogs.com/zxhl/p/4893055.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值