A - Johnny and Ancient Computer
这道题的题意大概是这样的:你有两个数,要求你如何在规定的操作内用最小的步骤将其中一个数变为另一个数。
规定的操作:是x*2,x*4,x*8,x/2(如果x mod 2==0),x/4(如果 x mod 4==0),x/8(如果x mod 8==0)
这道题:我个人的思路是:只做乘法,因为两个数互相变化所需要的操作是一样的,那么我将小的数变为大的数所进行的操作就是这道题的解,小的变为大的只需要考虑乘法就可以了。然后乘法的操作都是2的倍数,那么我们只需要将大的
#include<iostream> #include<algorithm> #include<cstdio> using namespace std; typedef long long LL; int main(){ int t; LL a, b; scanf("%d", &t); while(t--){ scanf("%lld%lld", &a, &b); int flag = 1; int cnt = 0; int flag1 = 0; LL c = max(a, b); LL d = min(a, b); if(c%d==0&&c!=d){ LL e = c / d; while(e!=1){ //如果能够转化 那么e一定是2的倍数 if(e%2!=0){ //因为操作乘法都是2的倍数 如果不是2的倍数 那么无法转化,就输出-1 flag = 0; break; } else e = e / 2; cnt++;//代表e是2的几次方 } if(!flag){ printf("-1 "); } else { int x=0;//x代表乘以2的操作数 int y = 0;//y代表乘以4的操作数 int z = 0;//z代表乘以8的操作数 for (int i = 0; i <= cnt;i++){//2是2的1次方 for (int j = 0; j <= cnt / 2;j++){//4是2的2次方 for (int k = 0; k <= cnt /3;k++){ //8是2的3次方 if(k*3+2*j+i==cnt){ //如果相等 则证明已经找到 跳出循环 x = k; y = j; z = i; flag1 = 1; break; } } if(flag1) break; } if(flag1) break; } printf("%d ", x+ y+ z); } } else if(c==d&&c%d==0){ printf("0 "); } else printf("-1 "); } }
数除以小的数,然后看它是2的几次方,枚举。具体的还是看代码比较清楚。