寫在前面
360技術筆試編程題
前面的選擇題各式各樣,感覺都答懵了~所以編程題時間就不夠了,這個真是經驗之談,以后還是先做編程,再做選擇。。。再多幾分鍾,就能調出來。。摔杯啊~~~~所以像我這種的,最后只是寫上去,第二題提交的還有包名,估計編譯都不過。。。。以后筆試先做編程,先編程,先編程。重要的事情說三遍。
好了 正題開始。
1、第一題
題目描述
為考驗各自的數學能力,小B和小A經常在一起玩各種數值游戲,這一次他們又有了一種新玩法。每人從指定的數值范圍中各自選擇一個整數,記小A選擇的數值為a,小B選擇的數值為b。他們用一個均勻分布的隨機數發生器在該數值范圍中隨機生成一個整數c,定義制勝的游戲規則為誰選的數離c近則誰取得勝利。由於小B是女生,特別定義當兩人的數與c之間的差值相等時,小B獲勝。
由於先前的游戲中,小A為表現紳士風度總是輸多贏少,因此他特別渴望這次能夠給小B比較深刻的映像,所以向你求助。你事先已經知道了小B所選的數值和指定的數值范圍,小A希望你幫他選擇一個數值使得他獲勝的概率最大。
輸入多行,每行一組數據,包含兩個正整數n和b,分別代表數值范圍和小B所需的數字,其中 1 <= b <= n <= 10^9.
每組輸入,單獨的行中輸出一個數,為小A所選的數字,使得小A獲勝的概率最大,若存在多個這樣的數,輸出最小的那個。
題目分析
這個題其實不難,但題意半天搞不懂,所以開始試了幾次都錯誤。
顯然看出,小A不一定贏,因為假設兩人都猜對,那也是小B獲勝。所以其實本題就是求出在所有情況下,小A獲勝概率最大的數,更直白的說,小A猜數結果從1到n,有n種情況,猜哪個數字使得獲勝概率最大。而只要小A猜測的結果比小B更接近c,就是獲勝。
import java.util.Scanner;
public class Main {
public static void main(String args[]) {
Scanner cin = new Scanner(System.in);
while (cin.hasNext()) {
int n = cin.nextInt();
int b = cin.nextInt();
int max = 0;
int index = 0;
for (int i = 1; i <= n; i++) { // 列舉小A的選擇求出,該選擇下對應的獲勝情況,
int win = 0; // 小A選擇i,隨機數為任意情況下小B獲勝大小
for (int c = 1; c <= n; c++) {
if (Math.abs(c - i) < Math.abs(c - b)) // 小A獲勝
win++;
}
if (win > max) {
max = win;
index = i;
}
}
System.out.println(index);
}
cin.close();
}
}
討論
評論區有人回復說用簡單的數學方法。就是說,給定區間1~n,判斷小B取值在中位數的哪側,也就是說,如果小B取值在中位數右側,那小A只要取值為小B取值數-1,反之,如果小B取值在中位數左側,那小A只要取值為小B取值數+1。更具體地說:
情況一:如果小B取值在中位數右側,隨機數的取值為1~n,所以如果小A只要取值為B-1,那么隨機數分布在小B左側的情況下,小A贏。(因為左側明顯多嘛)
反之。
代碼比較簡單,判斷和中位數的大小。然后輸出。
2、第二題
題目描述
小B最近迷上了字符串處理技術,他設計了各種處理方式,並計算字符串的屬性。這次也不例外,他定義了一種新的字符置換方式。小B研究的字符串由ASCII碼字母和“.”構成,這次的研究對象是“.”。他關心的對象是字符串中出現的連續兩個“.”。若每次操作把其中最開始的連續兩個“.”以一個“.”替代,則可以將函數f(s) 定義為使得串中不出現連續兩個“.”的最小置換次數。
現考慮m個字符替換操作,每次將指定位置的字符替換為給定的字符,求替換后函數f(s)的值。
輸入有若干行,沒組的第一行為兩個整數n和m,1 <= n, m <= 300000,表示字符串的長度和字符串替換操作的次數,第二行為所給的字符串,隨后緊跟着m行操作,每行由一個正整數x和一個字母c組成,表示將字符串位置m出的字符置換為字母c。
輸出:對每組輸入的每個置換操作,在單獨的行中輸出函數f(s)的結果。
題目分析
題目的關鍵是函數f(s)的實現。
一個連續“.”,返回0;
兩個連續“.”,返回1;
三個連續“.”,返回2;
四個連續“.”,返回3;
...
所以規律就是有n個連續“.”,返回n-1;
這個題目我卡在字符串處理上,你敢信,一種就是像我下面寫的這種方法,另一種就是可以轉換為字符數組,然后進行處理。
下面這個版本我本機測試通過
import java.util.Scanner;
public class Main {
public static int dealString(String str) {
int left1 = str.indexOf('.'), left2 = left1;
int count = 0;
while (left1 < str.length() && left2 < str.length()) {
if (str.charAt(left2) == '.') {
while (left2 < str.length() && str.charAt(left2) == '.')
left2++;
int tmp = left2 - left1 - 1;
count += tmp;
}
if (left2 < str.length() && str.charAt(left2) != '.') {
left2++;
left1 = left2;
}
}
return count;
}
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
while (cin.hasNext()) {
int n = cin.nextInt();
int m = cin.nextInt();
String str = cin.next();
for (int i = 1; i <= m; i++) {
int index = cin.nextInt();
String ch = cin.next();
String tmp = "";
if (index > 1)
tmp = str.substring(0, index - 1);
str = tmp + ch + str.substring(index);//替換字符
int count = dealString(str);
System.out.println(count);
}
}
cin.close();
}
}
如果有更好的解決辦法,歡迎大家一起討論。