算法题:升级之路(网易招聘笔试)

名企笔试:网易招聘笔试(升级之路)
题目描述

小易经常沉迷于网络游戏.有一次,他在玩一个打怪升级的游戏,他的角色的初始能力值为 a.在接下来的一段时间内,他将会依次遇见n个怪物,每个怪物的防御力为b1,b2,b3…bn. 如果遇到的怪物防御力bi小于等于小易的当前能力值c,那么他就能轻松打败怪物,并 且使得自己的能力值增加bi;如果bi大于c,那他也能打败怪物,但他的能力值只能增加bi 与c的最大公约数.那么问题来了,在一系列的锻炼后,小易的最终能力值为多少?

输入描述:

对于每组数据,第一行是两个整数n(1≤n<100000)表示怪物的数量和a表示小易的初始能力值.
第二行n个整数,b1,b2…bn(1≤bi≤n)表示每个怪物的防御力

输出描述:

对于每组数据,输出一行。每行仅包含一个整数,表示小易的最终能力值

输入例子:

3 50
50 105 200
5 20
30 20 15 40 100

输出例子:

110
205

 

java版本的代码实现:

package cn.cat.algorithm;

import java.util.ArrayList;
import java.util.List;


public class GameUpgrade {

	/**
	 *  分析:此题的难点在于求公约数,首先分别求出两个数的约数,然后比较得出最大公约数。
	 *       求约数时,从1开始相除,能除尽的则除数和商都是约数,然后依次递增逐个尝试相除,
	 *       求约数时有个小技巧,依次递增的时候,最大数应该是被求数/2,减少循环次数。
	 * 
	 * @Description: 
	 * @author gwj
	 * @Created 2018年4月18日 上午10:05:17 
	 * @param args
	 */
	public static void main(String[] args) {
		int[] base = new int[]{3, 50};
		int[] monsters = new int[]{50, 105, 200};
		play(base, monsters);
		
		base = new int[]{5, 20};
		monsters = new int[]{30, 20, 15, 40, 100};
		play(base, monsters);
	}
	
	/** 开始游戏
	 * @Description: 
	 * @author gwj
	 * @Created 2018年4月18日 上午10:49:49 
	 * @param base 基本信息
	 * @param monsters 怪兽防御力
	 */
	private static void play(int[] base, int[] monsters) {
		//小易能力值
		int ability = base[1];
		for (int monster : monsters) {
			if (monster > ability) {
				ability += evelMaxCommonFactor(monster, ability);
			} else {
				ability += monster;
			}
		}
		
		System.out.println(ability);
	}
	
	
	/** 求两个数的最大公约数
	 * @Description: 
	 * @author gwj
	 * @Created 2018年4月18日 上午10:38:42 
	 * @param num1
	 * @param num2
	 * @return 最大公约数
	 */
	private static int evelMaxCommonFactor(int num1, int num2) {
		Integer[] num1Factors = evelFactor(num1);
		Integer[] num2Factors = evelFactor(num2);
		
		int maxCommonFactor = -1;
		for (Integer f1 : num1Factors) {
			for (Integer f2 : num2Factors) {
				//注意两个Integer对象比较,不要直接用==,需要用equals方法。
				if ((f1.equals(f2)) && f1 > maxCommonFactor) {
					maxCommonFactor = f1;
					break;
				}
			}
		}
		return maxCommonFactor;
	}
	
	/** 求所有约数
	 * @Description: 
	 * @author gwj
	 * @Created 2018年4月18日 上午10:35:40 
	 * @param num 被求数
	 * @return 约数集
	 */
	private static Integer[] evelFactor(int num) {
		//此中间值如果不能被2整除,则会舍去小数
		int middle = num / 2;
		List<Integer> factors = new ArrayList<Integer>();
		for (int i = 1; i < middle; i++) {
			//能被整除的则为约数
			if (num % i == 0) {
				//除数和商都是约数,如果两个数一样,则只取一个。
				factors.add(i);
				int result = num / i;
				if (result != i) {
					factors.add(result);
				}
			}
		}
		
		return factors.toArray(new Integer[factors.size()]);
	}
	

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值