牛客网-Various Tree(BFS)

链接: https://www.nowcoder.com/acm/contest/106/J

来源:牛客网

Various Tree

时间限制:C/C++ 1秒,其他语言2秒

空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

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.

题意:给定两个正整数A,B和四种变化方式y=x+1,y=x-1,y=x+f(x),y=x-f(x).其中f(x)的定义为x转化为二进制数后其中1的个数,然后求将A变为B最少需要几次操作。

题解:一开始觉得是贪心,然后发现贪心的时候总是不能保证最优,而且还存在时间复杂度的问题。但是贪心的时候想到的一个条件启发了我,先到达的点一定是最优的,那么是不是就Di算法求最短路很像呢,然后顺着思路想下去,发现其实可以用bfs求A到B的最短路,移动方式一共有四种,所以就是隐藏了一个图。时间复杂度为O(n)

代码:

import java.util.Scanner;
import java.util.LinkedList;
import java.util.Queue;

public class Main {

	private final static int maxn = 1000025;
	private static int [] ans = new int[maxn];
	
	public void init(){
		for(int i=0; i<maxn; i++){
			ans[i] = -1;
		}
	}
	
	public int f(int k){
		int counter = 0;
		while(k != 0){
			if((k&1) == 1){
				counter++;
			}
			k >>= 1;
		}
		return counter;
	}
	
	public void bfs(int k, int y){
		Queue<Integer> q = new LinkedList<Integer>();
		q.add(k);
		int deep = 1;
		while(!q.isEmpty()){
			int length = q.size();
			for(int i=0; i<length; i++){
				int x = q.poll(), t = f(x);
				if(x+1<maxn && ans[x+1] == -1){
					ans[x+1] = deep;
					q.add(x+1);
				}
				if(x-1>=0 && ans[x-1] == -1){
					ans[x-1] = deep;
					q.add(x-1);
				}
				if(x+t<maxn+20 && ans[x+t] == -1){
					ans[x+t] = deep;
					q.add(x+t);
				}
				if(x-t>=0 && ans[x-t] == -1){
					ans[x-t] = deep;
					q.add(x-t);
				}
			}
			deep++;
			if(ans[y] != -1)
				return;
		}
	}
	
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int a = in.nextInt();
		int b = in.nextInt();
		
		Main m = new Main();
		m.init();
		ans[a] = 0;
		m.bfs(a, b);
		System.out.println(ans[b]);
		in.close();
	}

}

有些题可能用一些看起来没什么关系的算法求解,取决自己的建模能力和算法理解深度了,感觉这个bfs还是考的很好的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值