练习cf1362A. Johnny and Ancient Computer
题目如下
A. Johnny and Ancient Computer
time limit per test1 second
memory limit per test256 megabytes
Johnny has recently found an ancient, broken computer. The machine has only one register, which allows one to put in there one variable. Then in one operation, you can shift its bits left or right by at most three positions. The right shift is forbidden if it cuts off some ones. So, in fact, in one operation, you can multiply or divide your number by 2, 4 or 8, and division is only allowed if the number is divisible by the chosen divisor.
Formally, if the register contains a positive integer 𝑥, in one operation it can be replaced by one of the following:
𝑥⋅2
𝑥⋅4
𝑥⋅8
𝑥/2, if 𝑥 is divisible by 2
𝑥/4, if 𝑥 is divisible by 4
𝑥/8, if 𝑥 is divisible by 8
For example, if 𝑥=6, in one operation it can be replaced by 12, 24, 48 or 3. Value 6 isn't divisible by 4 or 8, so there're only four variants of replacement.
Now Johnny wonders how many operations he needs to perform if he puts 𝑎 in the register and wants to get 𝑏 at the end.
Input
The input consists of multiple test cases. The first line contains an integer 𝑡 (1≤𝑡≤1000) — the number of test cases. The following 𝑡 lines contain a description of test cases.
The first and only line in each test case contains integers 𝑎 and 𝑏 (1≤𝑎,𝑏≤1018) — the initial and target value of the variable, respectively.
Output
Output 𝑡 lines, each line should contain one integer denoting the minimum number of operations Johnny needs to perform. If Johnny cannot get 𝑏 at the end, then write −1.
题目大意
每组有两个数组成,分别是现有的数和目标值,可以通过对现有的数进行左移动和右移的操作来使得现有数变成目标值;
左右移分别代表着乘,除;
移动的大小有3种,分别是2,4,8;
每次对现有数进行移动,若可以移动输出最小步数,否则输出-1.
题目分析
要使现有数通过上述操作成为目标数,需要先判断可能性:
步数大小固定,所以确定一方一定能被另一方整除,并且一定可以通过2,4,8的步数来完成;
通过每次除2来获得最大步数,
点击查看代码
}else if(max(n, target) % min(n, target) == 0){
unsigned long long big = max(n, target);
unsigned long long small = min(n, target);
unsigned long long m = big / small;
while(m % 2 == 0){
m /= 2;
cnt++;
}
if(m == 1){ //检查最多有几次shift3,再计算剩下的步数;
ans = cnt / 3 + (cnt % 3) / 2 + (cnt % 3) % 2;
}
}
完整代码
点击查看代码
#include <iostream>
#include <algorithm>
using namespace std;
int main(){
int t;
scanf("%d", &t);
while(t--){
unsigned long long n, target;
cin >> n >> target;
int cnt = 0,ans = -1;
if(target == n){
ans = 0;
}else if(max(n, target) % min(n, target) == 0){
unsigned long long big = max(n, target);
unsigned long long small = min(n, target);
unsigned long long m = big / small;
while(m % 2 == 0){
m /= 2;
cnt++;
}
if(m == 1){ //检查最多有几次shift3,再计算剩下的步数;
ans = cnt / 3 + (cnt % 3) / 2 + (cnt % 3) % 2;
}
}
printf("%d\n", ans);
}
return 0;
}

浙公网安备 33010602011771号