3 1 1 1 2 2 4
0 -1 1
/************************************************************************/
附上该题对应的中文题
给出两个数N和M。 N每次可以乘上一个自己的因数变成新的N。 求最初的N到M至少需要几步。 如果永远也到不了输出−1。
第一行读入一个数T表示数据组数。 接下来T行,每行两个数N和M。 T≤1000, 1≤N≤1000000,1≤M≤263. 注意M的范围。hack时建议输出最后一行的行末回车;每一行的结尾不要输出空格。
对于每组数据,输出一个数表示答案。
3 1 1 1 2 2 4
0 -1 1
出题人的解题思路:
如果A大于B那么显然无解。
考虑把A和B分解质因数。
若B存在A没有的质因数也显然无解。
对于某一个A的质因数的次数。为了加速接近B,它一定是每次翻倍,最后一次的时候把剩下的加上。
那么答案就是最小的k使得2k∗Anum≥Bnum。
最后把每个质因数的答案max起来即可。
感觉本场比赛没有trick(雾~),我就打算加入一个很经典的trick:
B可以刚好等于263,这样就要开unsigned long long。
同时我还在题目里特别提醒了“注意M的范围”
可惜仍然有很多选手没有注意。
这里我表示歉意,也希望你们以后可以更加仔细一点。
对于题目的解法,我相信通过出题人的解题报告,多多少少都能明白一点,在此,我也不多说,有不明白的可以留下评论#pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<string.h> #include<queue> #include<stack> #include<math.h> #include<vector> #include<map> #include<set> #include<stdlib.h> #include<cmath> #include<string> #include<algorithm> #include<iostream> #define exp 1e-10 using namespace std; const int N = 1000000; const int inf = 1000000000; const int mod = 2009; __int64 gcd(__int64 a,__int64 b) { if(a%b) return gcd(b,a%b); return b; } int main() { int t,i,k,ans; __int64 n,m; scanf("%d",&t); while(t--) { ans=0; scanf("%I64d%I64d",&n,&m); while(n!=m) { if(m%n) { puts("-1"); break; } k=gcd(m/n,n); if(k==1) { puts("-1"); break; } n*=k; ans++; } if(n==m) printf("%d\n",ans); } return 0; }菜鸟成长记