1. 程式人生 > >招商銀行信用卡2018春季招聘研發(第一批)程式設計題

招商銀行信用卡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 + ba * b何時最大,那必然是ab儘量靠近時才最大,現在這個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();
    }
}