题目链接:https://www.nowcoder.com/acm/contest/106/J
题目描述:
It‘s universally acknowledged that there’re innumerable trees in the campus of HUST. And there are many different types of trees in HUST, each of which has a number represent its type. The doctors of biology in HUST find 4 different ways to change the tree’s type x into a new type y:
1. y=x+1
2. y=x-1
3. y=x+f(x)
4. y=x-f(x)
The function f(x) is defined as the number of 1 in x in binary representation. For example, f(1)=1, f(2)=1, f(3)=2, f(10)=2.
Now the doctors are given a tree of the type A. The doctors want to change its type into B. Because each step will cost a huge amount of money, you need to help them figure out the minimum steps to change the type of the tree into B.
Remember the type number should always be a natural number (0 included).
输入描述:
One line with two integers A and B, the init type and the target type.
输出描述:
You need to print a integer representing the minimum steps.
示例1
输入
5 12
输出
3
说明
The minimum steps they should take: 5->7->10->12. Thus the answer is 3.
分析:注意到type number必须是自然数, 所以不能一直贪心下去,需要对目标数相邻的两个数进行bfs操作,取最小步数
#include <iostream>
#include <queue>
using namespace std;
struct node {
int type_num;
int step;
};
int OneBitNum(int num) {
int ans = 0;
while (num) {
if (num & 1) ans += 1;
num >>= 1;
}
return ans;
}
int BFS(int start, int end) {
int step = -1;
queue<node> q;
node new_node;
new_node.type_num = start;
new_node.step = 0;
q.push(new_node);
while (!q.empty()) {
node old_node = q.front();
q.pop();
if (old_node.type_num == end) {
step = old_node.step;
break;
}
for (int i = 1; i <= 4; i++) {
switch (i)
{
case 1:
new_node.type_num = old_node.type_num + 1;
break;
case 2:
new_node.type_num = old_node.type_num - 1;
break;
case 3:
new_node.type_num = old_node.type_num + OneBitNum(old_node.type_num);
break;
default:
new_node.type_num = old_node.type_num - OneBitNum(old_node.type_num);
break;
}
new_node.step = old_node.step + 1;
q.push(new_node);
}
}
return step;
}
void Solve(int a, int b) {
int front = a;
int step = 0;
int back, step1, step2;
if(a <= b) {
while (front < b) {
int n = OneBitNum(front);
back = front;
if (n > 1) front += n;
else front += 1;
step++;
}
}
else {
while (front > b) {
int n = OneBitNum(front);
back = front;
if (n > 1) front -= n;
else front -= 1;
step++;
}
}
if (front != b) {
step1 = BFS(back, b) + step - 1;
step2 = BFS(front, b) + step;
step = step1 >= step2 ? step2 : step1;
}
cout << step << '\n';
}
int main() {
int a, b;
cin >> a >> b;
Solve(a, b);
return 0;
}
参考:https://www.nowcoder.com/acm/contest/view-submission?submissionId=26018280