打表技巧
打表找规律
-
某个面试题,输入参数类型简单,并且只有一个实际参数
-
要求的返回值类型也简单,并且只有一个
-
用暴力方法,把输入参数对应的返回值,打印出来看看,进而优化code
小虎去买苹果,商店只提供两种类型的塑料袋,每种类型都有任意数量。
1)能装下6个苹果的袋子
2)能装下8个苹果的袋子
小虎可以自由使用两种袋子来装苹果,但是小虎有强迫症,他要求自己使用的袋子数量必须最少,且使用的每个袋子必须装满。
给定一个正整数N,返回至少使用多少袋子。如果N无法让使用的每个袋子必须装满,返回-1
public class AppleMinBags {
public static int minBags(int a) {
int bag6 = 0;
int bag8 = a/8;
int rest = a - bag8 * 8;
int rest6 = -1;
while(bag8>=0 && rest<24) {
rest6 = rest%6 == 0 ?rest/6 :-1;
if(rest6 != -1) {
bag6 = rest6;
break;
}
rest = a-8*(--bag8);
}
return bag6 == -1 ?-1 :bag6+bag8;
}
//发现的规律是从18开始具有明显的分组倾向,每8个一组,
//而且其中奇数返回结果是-1,其余结果是当前组数+3,18以内的单独处理
public static int minBag2(int a) {
if( (a & 1) !=0) {
return -1;
}
if(a < 18) {
return a==0 ?0 :(a==6||a==8) ?1:
(a==12||a==14||a==16) ?2 :-1;
}
return (a-18)/8+3;
}
public static void main(String[] args) {
for (int i = 0; i < 101; i++) {
System.out.println(i+" : "+minBags(i));
}
}
}
给定一个正整数N,表示有N份青草统一堆放在仓库里有一只牛和一只羊,牛先吃,羊后吃,它俩轮流吃草不管是牛还是羊,每一轮能吃的草量必须是:
1,4,16, 64…(4的某次方)
谁最先把草吃完,谁获胜
假设牛和羊都绝顶聪明,都想赢,都会做出理性的决定根据唯一的参数N,返回谁会赢
public class EatGrass {
public static String winner1(int n) {
//0 1 2 3 4
//后 先 后 先 先
if(n<5) {
return (n==0 || n==2) ?"后手" :"先手";
}
int base=1; //当前先手决定吃的草数
while (base<=n){
// 当前一共n份草,先手吃掉的是base份,n - base 是留给后手的草
// 母过程 先手 在子过程里是 后手
if(winner1(n-base).equals("后手")) {
return "先手";
}
if (base*4>n) {
break;
}
base = base*4;
}
return "后手";
}
public static String winner2(int n) {
if(n%5==0||n%5==2) {
return "后手";
} else {
return "先手";
}
}
public static void main(String[] args) {
for(int i=0;i<50;i++) {
System.out.println(i + "---> " + winner1(i));
}
}
}
连续M个正数和
定义一种数:可以表示成若干(数量>1)连续正数和的数比如:
5 = 2+3,5就是这样的数12 = 3+4+5,12就是这样的数
1不是这样的数,因为要求数量大于1个、连续正数和2 = 1+1,2也不是,因为等号右边不是连续正数
给定一个参数N,返回是不是可以表示成若干连续正数和的数
public class MSumToN {
public static boolean isMSum1(int num) {
for (int i = 1; i <= num; i++) {
int sum = i;
for (int j = i + 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) {
if (num < 3) {
return false;
}
return (num & (num - 1)) != 0;
}
public static void main(String[] args) {
for (int num = 1; num < 200; num++) {
System.out.println(num + " : " + isMSum1(num));
}
System.out.println("test begin");
for (int num = 1; num < 5000; num++) {
if (isMSum1(num) != isMSum2(num)) {
System.out.println("Oops!");
}
}
System.out.println("test end");
}
}
(num & (num - 1)) == 0 num是2的某次方
(num & (num - 1)) != 0 num不是2的某次方
每个人都有潜在的能量,只是很容易被习惯所掩盖,被时间所迷离,被惰性所消磨~