部門優化
某公司內有 4 個項⽬組,項⽬組 A、B、C、D,項⽬組A現有10人,項⽬組B現有7人,項⽬組C現 有5人,項⽬組D現有4人。為了實現跨項⽬組協作,公司決定每⽉從⼈數最多的項⽬組中抽調 3 ⼈ 出來,到其他剩下 3 組中,每組 1 人,這稱之為一次調整優化(亦即經過第⼀次調整后,A組有7 人,B組有8人,C組有6人,D組有5人)。 那么請問,經過十年的優化調整后,各項目組各有幾人? 編程求解該問題,並思考是否為最優解。
解題思路
最直觀的解題思路就是,每次都進行一次優化,根據優化規則一直優化120次。
每次優化其實就是從數組中選出最大值,然后最大值-3,其他元素+1。
代碼邏輯實現:
public class Solution {
public static void main(String[] args) {
test1();
}
public static void test1(){
//初始數組
int[] arr={10,7,5,4};
//一個月優化一次,十年一共120次
for (int i = 0; i <120 ; i++) {
arr=optimize(arr);
}
//打印優化十年后的結果
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
/**
* 優化的邏輯
* @param arr 目標數組
* @return 優化后的數組
*/
private static int[] optimize(int[] arr){
int index=getMaxIndex(arr);
for (int i = 0; i < arr.length; i++) {
if(index==i){
arr[i]-=3;
}else{
arr[i]+=1;
}
}
return arr;
}
/**
* 獲取數組最大值的索引
* @param arr 目標數據
* @return 最大值的索引
*/
private static int getMaxIndex(int [] arr){
int max=0;
int index=0;
for (int i = 0; i < arr.length; i++) {
if(arr[i]>max){
max=arr[i];
index=i;
}
}
return index;
}
}
總結規律之后發現,這個並非最優解。前幾次的結果如下所示:
優化1次:10 7 5 4
優化2次:7 8 6 5
優化3次:8 5 7 6
優化4次:5 6 8 7
優化5次:6 7 5 8
優化6次:7 8 6 5
此后的結果一直在7,8,6,5之間變換。除去第一次的結果,從第二次開始每4個數據之后開始重復。也就是說一共119次優化,前116次優化之后結果為7 8 6 5,再優化三次,得出結果為6 7 5 8。
邀請碼檢測
某產品的⽤戶注冊邀請碼為⼀串有⼩寫字⺟和數字組成的字符串,字符串⻓度為16。當⽤戶數據邀 請碼的時候,系統需要對邀請碼做有效性驗證,假設驗證規則如下: 1、 從序列號最后⼀位字符開始,逆向將奇數位(1、3、5等等)相加; 2、從序列號最后⼀位數字開始,逆向將偶數位數字,先乘以2(如果乘積為兩位數,則將其減去 9),再求和; 3、將奇數位總和加上偶數位總和,結果可以被10整除; 4、⼩寫字⺟對應數值,可由下⾯鍵值對確定; [(a,1), (b,2), (c,3)…,(i,9), (j,1), (k, 2)…],亦即,按字⺟順序,1-9循環。 輸⼊:輸⼊16位字符串,表示邀請碼 輸出:輸出“ok”或者“error”
解題思路
這個題真沒什么好說的,按題目做就行了。主要是要知道ASCLL碼對應的值
public class inviteCodeSolution {
public static void main(String[] args) {
String s = "123456789123456C";
System.out.println(isVerify(s));
}
/**
* 對校驗結果進行格式化
* @param s 傳入的邀請碼
* @return 如果合法則為ok,否則為error
*/
public static String isVerify(String s) {
boolean result = false;
try {
result = verify(s);
} catch (Exception e) {
e.printStackTrace();
}
return result ? "ok" : "error";
}
/**
* 校驗邀請碼是否合法
* @param s 傳入的邀請碼
* @return true合法,false不合法
* @throws Exception 傳入的數據包含除數字和小寫字母以外的字符
*/
public static boolean verify(String s) throws Exception {
char[] chars = s.toCharArray();
int sumOdd = 0, sumEven = 0;
//逆序遍歷
for (int i = chars.length - 1; i >= 0; i--) {
//如果是偶數位
if (i % 2 == 0) {
sumEven += getMapData(chars[i]) > 4 ? ((getMapData(chars[i]) * 2) - 9) : (getMapData(chars[i]) * 2);
} else {
//奇數位
sumOdd += getMapData(chars[i]);
}
}
System.out.println("偶數和:" + sumEven + ",奇數和:" + sumOdd);
return (sumEven + sumOdd) % 10 == 0;
}
/**
* 獲取映射的值
*
* @param c 傳入的字符
* @return c的實際值
*/
public static int getMapData(char c) throws Exception {
int result;
//如果是小寫字母,則按規則映射成數字
if (c >= 97 && c <= 122) {
result = (c - 96) % 9;
} else if (c >= 48 && c <= 57) {
result = c - 48;
} else {
//非數字和小寫字母則拋出異常
throw new Exception("數據錯誤");
}
return result;
}
}