2019屆百度秋招筆試題【混戰世界】【字符串計數】

混戰世界

1.題目描述

 戰亂年代。整個世界各個軍閥的英團泄戰,你是P7軍團的戰略參謀,你手下n(保證爲3的倍數)個士兵,第i個土兵的物理攻擊數值爲Ai,魔法攻擊數值爲Bi,你需要將這些士兵三等分爲三個連,

  • 第一個連需要去物理空間參加物理對抗戰爭,戰鬥力估值W1爲士兵的物理攻擊數值之和:
  • 第二個連需要去魔法空間參加魔法對抗戰爭,戰鬥力估值W2爲士兵的魔法攻擊數值之和:
  • 第三個連需要去虛幻空間參加物理魔法裝備的綜合對抗戰爭,戰鬥力估值W3爲所有士兵的物理攻擊數值、魔法攻擊數值之和除以2。

你希望W1+W2+W3最大。這樣才最有可能勝利。
輸入描述:
 第一行一個整數n,保證爲3的倍數。(3≤n≤1000)
  第二行n個整數, 第i個數表示Ai。
  第三行n個整數,第i個數表示Bi。(I≤Ai, Di≤1000)
輸出描述:
 一個小數,表示最大數之和,保留兩位小數(四捨五入)。
輸入樣例:
 6
 1 7 3 4 5 9
 2 3 9 4 3 3
輸出樣例:
 35.00

2.解題思路

設一個人的物理值爲A,魔法值爲B.
派去一連可得A的貢獻,二連可得B, 三連可得(A+B)/2。

  • 去一連與去三連相比差了(A-B)/2.去二連比去三連也差(A-B)/2。這樣,可以根據每個人的A-B數值進行排序,
  • 由題意可知,A越大越適合去1連,B越大越適合去2連,故(A-B)/2中,較大者1連,較小者去2連,中間的去3連。

3.代碼

import java.text.DecimalFormat;
import java.util.*;
public class Main {
    public static void main(String[] args) {
//        int a[] = {1,7,3,4,5,9};
//        int b[] = {2,3,9,4,3,3};
//        System.out.println(String.format("%.2f",solution(a,b)));
		Scanner sr = new Scanner(System.in);
		int n = sr.nextInt();
		int a[] = new int[n];
		int b[] = new int[n];
		for(int i = 0;i<n;i++){
		  a[i] = sr.nextInt();
		}
		for(int i = 0;i<n;i++){
		  b[i] = sr.nextInt();
		}
        solution(a,b);
    }
    public static void solution(int A[],int B[]){
        Diff []list= new Diff[A.length];
        for(int i = 0;i<A.length;i++){
            list[i] = new Diff(i,A[i] - B[i]);
        }
        //裏面的list已經從小到大排序了
        Arrays.sort(list);
        double res = 0;
        //取值,較小的去2連,中間的去三連,較大的去1連
        int Avglen = list.length/3;

        for(int i = 0;i<list.length;i++){
            //(A-B)較小者去2連
            if(0<=i && i<Avglen ){
                res += B[list[i].index];
                //(A-B)中間者去3連,這裏注意要乘個1.0,避免除以2會強轉爲int型
            }else if(i >= Avglen && i< 2 *Avglen ){
                res += ((A[list[i].index] + B[list[i].index])*1.0)/2;
            }else{
                //(A-B)較大者去1連
                res += A[list[i].index];
            }
        }
        DecimalFormat df = new DecimalFormat("#.00");
        System.out.println(df.format(res));

    }
    //用於存儲索引座標以及(Ai-Bi)
    static class Diff implements Comparable{
        int index;
        int value;
        public Diff(int index, int value) {
            this.index = index;
            this.value = value;
        }
        public int getIndex() {
            return index;
        }
        //按照(A-B)/2 進行排序
        @Override
        public int compareTo(Object o) {
          Diff diff = (Diff) o;
          if(this.value > diff.value)
              return 1;
          else if(this.value == diff.value)
              return 0;
          else
              return -1;
        }
    }
}

在這裏插入圖片描述

拓展

java裏面保留數值的位數(四舍五人)
方法1:
   System.out.println(String.format("%.2f",num));
方法2:
   DecimalFormat df = new DecimalFormat("#.00");
   System.out.println(df.format(num));

字符串計數

1.題目描述

  給定一個僅由小寫字母組成且長度不超過10^6的字符串,將首字符移到末尾並記錄所得的字符串,不斷重複該操作,雖然記錄了無限個字符串,但其中不同字符串的數目卻是有限的,那麼一共記錄了多少個不同的字符串?
樣例輸入
   abab
樣例輸出
   2
樣例解釋
   記錄了abab和baba這2個不同的字符串。

2.解題思路

方法1:對字符串不斷進行重組,對不同的字符串進行入隊,最後返回隊列的大小即爲不同的字符串個數

方法2:利用kmp算法的next數組,可以求出字符串的最小循環週期T,這就是答案

3.代碼

方法1:

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sr = new Scanner(System.in);
        String str = sr.nextLine();
        System.out.println(solution(str));
    }
     public static int solution(String str){
        if(str == null )
            return 0;
        else if(str.trim().equals(""))
            return 1;
        else if(str.length() == 0)
            return 0;
        else{
            List<String> list = new ArrayList<>();
            String temp = str;
            list.add(str);
            for(int i = 0;i<str.length();i++){
                //首字符移到末尾並記錄所得的字符串,
                temp = temp.substring(1,temp.length())+temp.charAt(0);
                //如果list裏面沒有該字符串則加入list
                if(!list.contains(temp)){
                    list.add(temp);
                }
            }
            return list.size();
        }
    }

請檢查是否存在數組越界等非法訪問情況
case通過率爲50.00%


不知道哪裏錯了。哭泣

方法2:KMP算法

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sr = new Scanner(System.in);
        String str = sr.nextLine();
        System.out.println(kmp(str));
    }
     public static int kmp(String str){
        int len = str.length();
        int [] next = new int[len+1];
        next[0] = -1;
        int k = -1;
        int j  = 0;
        while (j < len ){
            if(k== -1 || str.charAt(k) == str.charAt(j)){
                next[++j] = ++k;
            }else{
                k = next[k];
            }
        } 
        //next[j] = k 代表p[j] 之前的模式串子串中,有長度爲k 的相同前綴和後綴,這裏next[len]表示len-1之前的模式串,即爲str時,有k的相同的前綴和後綴
        //所以循環週期T爲 總長度-相同前綴數
        int res = len % (len - next[len]);
        if(res != 0)
            return len;
        else
            return len-next[len];
    }
}

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章