根据对数器找规律

744 阅读2分钟

给定一个正整数N,返回至少使用多少袋子装苹果

#打表法

小虎去买苹果,商店只提供两种类型的塑料袋,每种类型都有任意数量。
1)能装下6个苹果的袋子
2)能装下8个苹果的袋子
小虎可以自由使用两种袋子来装苹果,但是小虎有强迫症,他要求自己使用的袋子数量必须最少,且使用的每个袋子必须装满。
给定一个正整数N,返回至少使用多少袋子。如果N无法让使用的每个袋子必须装满,返回-1

public static int minBags(int apple) {
		if (apple < 0) {
			return -1;
		}
		int bag8 = (apple >> 3);
		int rest = apple - (bag8 << 3);
		while(bag8 >= 0) {
			// rest 个
			if(rest % 6 ==0) {
				return bag8 + (rest / 6);
			} else {
				bag8--;
				rest += 8;
			}
		}
		return -1;
	}

	public static int minBagAwesome(int apple) {
		if ((apple & 1) != 0) { // 如果是奇数,返回-1
			return -1;
		}
		if (apple < 18) {
			return apple == 0 ? 0 : (apple == 6 || apple == 8) ? 1
					: (apple == 12 || apple == 14 || apple == 16) ? 2 : -1;
		}
		return (apple - 18) / 8 + 3;
	}

牛羊吃N份青草谁会赢

#打表法


给定一个正整数N,表示有N份青草统一堆放在仓库里有一只牛和一只羊,牛先吃,羊后吃,它俩轮流吃草不管是牛还是羊,每一轮能吃的草量必须是:
1,4,16,64…(4的某次方)
谁最先把草吃完,谁获胜假设牛和羊都绝顶聪明,都想赢,都会做出理性的决定根据唯一的参数N,返回谁会赢


// n份青草放在一堆
// 先手后手都绝顶聪明
// string "先手" "后手"
public static String winner1(int n) {
    // 0  1  2  3 4
    // 后 先 后 先 先
    if (n < 5) { // base case
        return (n == 0 || n == 2) ? "后手" : "先手";
    }
    // n >= 5 时
    int base = 1; // 当前先手决定吃的草数
    // 当前是先手在选
    while (base <= n) {
        // 当前一共n份草,先手吃掉的是base份,n - base 是留给后手的草
        // 母过程 先手 在子过程里是 后手
        if (winner1(n - base).equals("后手")) {
            return "先手";
        }
        if (base > n / 4) { // 防止base*4之后溢出
            break;
        }
        base *= 4;
    }
    return "后手";
}

==>

public static String winner2(int n) {
    if (n % 5 == 0 || n % 5 == 2) {
        return "后手";
    } else {
        return "先手";
    }
}

给定一个参数N,返回是不是可以表示成若干连续正数和的数


定义一种数:可以表示成若干(数量>1)连续正数和的数 比如: 5 = 2+3,5就是这样的数 12 = 3+4+5,12就是这样的数 1不是这样的数,因为要求数量大于1个、连续正数和 2 = 1 + 1,2也不是,因为等号右边不是连续正数 给定一个参数N,返回是不是可以表示成若干连续正数和的数

public static boolean isMSum1(int num) {
		for (int start = 1; start <= num; start++) {
			int sum = start;
			for (int j = start + 1; j <= num; j++) {
				if (sum + j > num) {
					break;
				}
				if (sum + j == num) {
					return true;
				}
				sum += j;
			}
		}
		return false;
	}

	public static boolean isMSum2(int num) {
//		
//		return num == (num & (~num + 1));
//		
//		return num == (num & (-num));
//		
//		
		return (num & (num - 1)) != 0;
	}