hdu 5505(数论-gcd的应用)

GT and numbers

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1818    Accepted Submission(s): 490


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.

T1000, 1N1000000,1M263.

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
 
题意:给出两个数 n,m ,n每次乘上某一个约数,问将 n->m 所需最少次数?
题解: n *(m/n) = m ,我们要让 n -> m,所以让n每次乘上最大的公约数,这是每次能够扩大的最大倍数,所以每次找到 d = gcd(n,m/n),n' = n*d ,(m/n)' = m/n/d,一直到 n==m ,当d = 1 时永远不可能到,break 输出 -1.
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
typedef unsigned long long ULL;
ULL n,m;
ULL gcd(ULL a,ULL b){
    return b==0?a:gcd(b,a%b);
}
int main(){
    int tcase;
    scanf("%d",&tcase);
    while(tcase--){
        scanf("%llu%llu",&n,&m);
        if(m%n!=0||n==1&&m!=1) {
            printf("-1
");
            continue;
        }
        if(m==n) {
            printf("0
");
            continue;
        }
        int ans = 0;
        ULL t = m/n;
        while(m!=n){
            ULL d = gcd(n,t);
            n = n*d;
            t = t/d;
            ans++;
            if(d==1) break;
        }
        if(m!=n) printf("-1
");
        else printf("%d
",ans);
    }
    return 0;
}
 
原文地址:https://www.cnblogs.com/liyinggang/p/5810677.html