打表技巧
阿新 • • 發佈:2022-04-18
打表找規律
-
某個面試題,輸入引數型別簡單,並且只有一個實際引數
-
要求的返回值型別也簡單,並且只有一個
-
用暴力方法,把輸入引數對應的返回值,打印出來看看,進而優化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的某次方