hdu5505 GT and numbers(贪心)

来源:互联网 发布:新浪微博数据抓取 编辑:程序博客网 时间:2024/06/12 01:37

Problem Description
You are given two numbers N and M.

Every step you can get a new N in the way that multiply N by a factor of N.

Work out how many steps can N be equal to M at least.

If N can’t be to M forever,print −1.

Input
In the first line there is a number T.T is the test number.

In the next T lines there are two numbers N and M.

T≤1000, 1≤N≤1000000,1≤M≤2^63.

Be careful to the range of M.

You’d better print the enter in the last line when you hack others.

You’d better not print space in the last of each line when you hack others.

Output
For each test case,output an answer.

Sample Input
3
1 1
1 2
2 4

Sample Output
0
-1
1

Source
BestCoder Round #60

题意:给出两个数N和M。N每次可以乘上一个自己的因数变成新的N。求最初的N到M至少需要几步。
如果永远也到不了输出−1。
解法:当存在M是N边化而来的时候:M/N是N乘一个数得到M,那么这个数与N的最大公约数维护N的变化是最优的。。之后的N=N*gcd(M/N,N)因为每次变化后,N都会变化。举个例子吧
4->8….gcd(2,4)=2 —N=8;
4->32—gcd(8,4)=4—->N=16;—gcd(2,16)=2—>N=16*2

特别注意的一点是M的取值是2^63。。。爆long long 了但是可以用unsigned long long 搞定,也可以写写大数来做。

#include<cstdio>#include<iostream>#include<algorithm>using namespace std;unsigned long long gcd(unsigned long long a,unsigned long long b){    return b==0?a:gcd(b,a%b);}int main(){    int O_O;    unsigned long long N,M;    scanf("%d",&O_O);    while(O_O--)    {        scanf("%llu %llu",&N,&M);        if(M%N!=0||N>M||(N==1&&N!=M))        {            printf("-1\n");            continue;        }        int cnt=0;        unsigned long long temp;        while(M!=N)        {            temp=gcd(M/N,N);            if(temp==1)            {                cnt=-1;                break;            }            N=N*temp; //新的N            cnt++;        }        printf("%d\n",cnt);    }    return 0;}
0 0
原创粉丝点击