hdu-5505(数论)
Posted LittlePointer
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu-5505(数论)相关的知识,希望对你有一定的参考价值。
题目链接:
GT and numbers
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
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.
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≤263.
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.
In the next T lines there are two numbers N and M.
T≤1000, 1≤N≤1000000,1≤M≤263.
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,m质因数分解,m如果能由n得来,那么分解后m的质因数与n的质因数相同,且每个质因数的个数不少于n;否则就不能由n得到;
最少的步数当然是对于每个质因数,贪心的去得到m中对应的质因数个数,最后答案就是所有质因数的个数变成m要求的个数的最大的那个;已经智障到不会写scanf了;
AC代码:
//#include <bits/stdc++.h> #include <iostream> #include <queue> #include <cmath> #include <map> #include <cstring> #include <algorithm> #include <cstdio> using namespace std; #define Riep(n) for(int i=1;i<=n;i++) #define Riop(n) for(int i=0;i<n;i++) #define Rjep(n) for(int j=1;j<=n;j++) #define Rjop(n) for(int j=0;j<n;j++) #define mst(ss,b) memset(ss,b,sizeof(ss)); typedef unsigned long long LL; const LL mod=1e9+7; const double PI=acos(-1.0); const int inf=0x3f3f3f3f; const int N=1e6+8; template<class T> void read(T&num) { char CH; bool F=false; for(CH=getchar();CH<‘0‘||CH>‘9‘;F= CH==‘-‘,CH=getchar()); for(num=0;CH>=‘0‘&&CH<=‘9‘;num=num*10+CH-‘0‘,CH=getchar()); F && (num=-num); } int stk[70], tp; template<class T> inline void print(T p) { if(!p) { puts("0"); return; } while(p) stk[++ tp] = p%10, p/=10; while(tp) putchar(stk[tp--] + ‘0‘); putchar(‘\n‘); } int prime[N]; struct node { int a[9],m; }po[N]; void Init() { for(int i=1;i<N;i++) { po[i].m=0; } for(int i=2;i<N;i++) { if(!prime[i]) { po[i].a[po[i].m++]=i; for(int j=2*i;j<N;j+=i) { po[j].a[po[j].m++]=i; prime[j]=1; } } } } LL check(int x) { LL s=1; for(int i=1;i<=x;i++) { s*=2; } return s; } int getans(int x,int y) { int l=0,r=(int)(log(y/x+1)/log(2.0))+1; while(l<=r) { int mid=(l+r)>>1; if(check(mid)*x>=y)r=mid-1; else l=mid+1; } return r+1; } void solve(int n,LL m) { if(n==1) { if(m==1)printf("0\n"); else printf("-1\n"); } else { int ans=0; int tempn=n; LL tempm=m; for(int i=0;i<po[n].m;i++) { int num1=0; while(tempn%po[n].a[i]==0) { tempn/=po[n].a[i]; num1++; } int num2=0; while(tempm%po[n].a[i]==0) { tempm/=po[n].a[i]; num2++; } if(num2<num1) { printf("-1\n"); return ; } ans=max(ans,getans(num1,num2)); } if(tempm>1)printf("-1\n"); else printf("%d\n",ans); } } int main() { Init(); int T; scanf("%d",&T); int n; LL m; while(T--) { read(n); scanf("%I64u",&m); solve(n,m); } return 0; }
以上是关于hdu-5505(数论)的主要内容,如果未能解决你的问题,请参考以下文章