招商銀行信用卡2018春季招聘研發(第一批)程式設計題
招商銀行信用卡的題難度一般,基本都能做出來,因此,解析就寫得簡單些了。而且題中沒有給出資料範圍,說明資料不會很大,因此這三個題都可以暴力求解。
第一題
題目
給出一個非空字串,判斷這個字串是否是由它的一個子串多次首尾拼接構成的。
輸入描述
非空字串
輸出描述
如果字串滿足上述條件,則輸出最長的滿足條件的子串;如果不滿足條件,則輸出
false
。
樣例
in: abcabc out: abc
解析
列舉子串的長度,從串長減一列舉到一,然後在陣列中迴圈判斷就行了,核心程式碼:
str.charAt(i) == str.charAt(i % ans)
程式碼
import java.util.*;
public class Main {
public Scanner cin = new Scanner(System.in);
Main() {
while (cin.hasNext()) {
String str = cin.next();
int ans = str.length() - 1;
for (int i = 0; ans > 0; ans--) {
for (i = 0; str .length() % ans == 0 && i < str.length()
&& str.charAt(i) == str.charAt(i % ans); i++) {
}
if (i == str.length())
break;
}
System.out.println(ans != 0 ? str.substring(0, ans) : "false" );
}
}
public static void main(String[] args) {
new Main();
}
}
第二題
題目
題目別人沒給我拍全,但是我知道這是一道LeetCode的原題,LeetCode現在有中國版的了,給出中國版的連結,即LeetCode - 22。
輸入描述
輸入為1個正整數
輸出描述
輸出為所有合法的字串,用英文逗號隔開
樣例
in: 2 out: (()),()()
解析
先給出在LeetCode上通過的程式碼:
class Solution {
public:
vector<string> generateParenthesis(int n) {
this->n = n;
vector<string> ret;
dfs(0, 0, 0, "", ret);
return ret;
}
private:
int n;
void dfs(int x, int l, int r, string str, vector<string> &ret)
{
if (x == 2 * n) {
ret.push_back(str);
return ;
}
if (l < n)
dfs(x + 1, l + 1, r, str + "(", ret);
if (r < n && l > r)
dfs(x + 1, l, r + 1, str + ")", ret);
}
};
給出一個整數n
,那麼生成的合法括號串的長度是2 * n
,那麼運用遞迴去列舉每個位置上的可能出現的字元(
,)
,列舉的時候要注意,當前位置可以放(
,但是能不能放)
就要看到目前為止放了多少個)
,如果(
的個數比)
多,那麼當前位置就可以放)
,這其實和用棧驗證括號串的合法性的思想是一樣的。
程式碼
import java.util.*;
public class Main {
public Scanner cin = new Scanner(System.in);
public int n;
public ArrayList<String> ans = new ArrayList<String>();
public void dfs(int x, int l, int r, String str) {
if (x == 2 * n) {
ans.add(str);
return ;
}
if (l < n)
dfs(x + 1, l + 1, r, str + "(");
if (r < n && l > r)
dfs(x + 1, l, r + 1, str + ")");
}
Main() {
while (cin.hasNext()) {
n = cin.nextInt();
ans.clear();
dfs(0, 0, 0, "");
for (int i = 0; i < ans.size(); i++)
System.out.print(ans.get(i) + (i != ans.size() - 1 ? "," : "\n"));
}
}
public static void main(String[] args) {
new Main();
}
}
第三題
題目
給出一個整數
n
,將n
分解成至少兩個整數之和,使得這些整數的乘積最大化,輸出能獲得的最大的乘積。
輸入描述
輸入為一個整數
輸出描述
輸出為一個整數
樣例
in: 10 out: 36
解析
這個題還是要一丁點數學知識的,給你一個數n = a + b
,a * b
何時最大,那必然是a
和b
儘量靠近時才最大,現在這個n
可以分解成多個數字相加,那麼這些數字相乘什麼時候最大呢,和兩個數字一樣,這些數字肯定也是都靠在一起才最大,什麼叫靠在一起呢,就是任意兩個數只差的絕對值小於等於1,那麼這些數字必然可以分解成x, x, x, ...,x + 1, x + 1, ...
這種形式。這麼一想,這個程式碼就好寫了,列舉其中的從1到n / 2
列舉x
,先看看可以分解成多少個數字,結果是n / x
,還剩下n % x
,把n % x
一個一個分配到之前的x
中,這裡要特別注意,n % x
有可能大於n / x
,這說明,把n % x
分配完,還有剩下的,不符合要求,而且這種情況肯定會在列舉x = x + 1
時會處理,因此過濾掉這種x
就行了。
程式碼
import java.util.*;
public class Main {
public Scanner cin = new Scanner(System.in);
Main() {
while (cin.hasNext()) {
long n = cin.nextLong(), ans = n / 2 * (n - n / 2);
for (int i = 1; i <= n / 2; i++) {
if (n / i <= n % i)
continue;
ans = (long) Math.max(ans, Math.pow(i + 1, n % i) * Math.pow(i, n / i - (n % i)));
}
System.out.println(ans);
}
}
public static void main(String[] args) {
new Main();
}
}