HDU 4320 Arcane Numbers 1


HDU 4320 Arcane Numbers 1:http://acm.hdu.edu.cn/showproblem.php?pid=4320
タイトル:
Arcane Numbers 1
Time Limit:2000/1000 MS(Java/Others)    メモリLimit:32768/32768 K(Java/Others)Total Submission(s):3017    Acceepted Submission(s):957
Problem Description
Vance and Shackler like playing game s.One day,they arararararararare playing a game caled“arcane numberss”.The game is pretty simple,Vance writes don a finite decimal undebase A,and then Shackletrtranansladededededededededededededededededededededededededededededededededededededededededededededededededededededededededededededededededededededededededededededededededededededeinininininininininininw given A and B、please help Vance to determine whether he will win or not.Note that they they ary playing this game using a mystery lagge so that A and B may be up to 10^12.
 
Input
The first line contains a single integer T,the number of test cases.
For each case,there’s a single line contains A and B.
 
Output
For each case,output“NO”if Vance will will the game.Other wise,print“YES”.See Sample Output for more detail.
 
Sample Input

   
   
   
   
3 5 5 2 3 1000 2000
 
Sample Output

   
   
   
   
Case #1: YES Case #2: NO Case #3: YES
タイトルの大意:
つの有限小数nはA、Bの2種類の進数の下で相互の転換を実現するかどうかを聞いて、できればYESを出力して、さもなくばNOを出力します。
テーマ分析:
任意の進数の下の1つの数nについては、整数と小数の2つの部分を含み、これらの2つの部分についてはそれぞれ「整数除算ベース逆取残」と「小数乗基正取」の原則に従う。
整数部分に対しては必ず2つの異なる進数間の変換が可能であり、小数部分に対しては数回の乗法を行った後、小数点以下の部分が0になり、進数変換が可能である。xに設定し、かつ小数点以下でk位を共有し、i番目の数字をaiとすれば、xは次のように表されることができる。
X=a 1*A^-1+a 2*A^-2+a 3*A^-3+…+ak*A^-k
この乗数の中にA^kが現れてこそ、進数変換が可能となります。すなわち、B^h(hは無限大)に因子A^kがあるかどうかを判断します。
算数の基本的な定理から、A^kの素数はAの素数と同じであることが分かります。
したがって、BにAのすべての素数係数が含まれている限り、hは必ず見つけられ、2つの進数の間で相互変換が可能である。
解決方法は以下の通りです。
AとBが互いに素養がないと、セグメントBにA/gcd(A,B)のすべての素因が含まれているかどうかを判定します。AとBが互いに素養すれば、A=1であれば、BにはAのすべての素因が含まれています。
コードの実装:
#include <iostream>
#include <cstdio>

using namespace std;

long long gcd(long long a,long long b)
{
    if(b==0)
    return a;
    else return gcd(b,a%b);
}

int main()
{
    int T;
    int casenum=0;
    long long a,b;
    long long d;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lld%lld",&a,&b);
        d=gcd(a,b);
        while(d!=1)
        {
            a/=d;
            d=gcd(a,b);
        }
        if(a==1)
        printf("Case #%d: YES
",++casenum); else printf("Case #%d: NO
",++casenum); } return 0; }