2016"百度之星" - 資格賽(Astar Round1)Problem A B C D--java代碼

Problem A : 字符串的Hash值
Problem Description
度熊手上有一本字典存儲了大量的單詞,有一次,他把所有單詞組成了一個很長很長的字符串。現在麻煩來了,他忘記了原來的字符串都是什麼,神奇的是他竟然記得原來那些字符串的哈希值。一個字符串的哈希值,由以下公式計算得到:

度熊手上有一本字典存儲了大量的單詞,有一次,他把所有單詞組成了一個很長很長的字符串。現在麻煩來了,他忘記了原來的字符串都是什麼,神奇的是他竟然記得原來那些字符串的哈希值。一個字符串的哈希值,由以下公式計算得到:
度熊手上有一本字典存儲了大量的單詞,有一次,他把所有單詞組成了一個很長很長的字符串。現在麻煩來了,他忘記了原來的字符串都是什麼,神奇的是他竟然記得原來那些字符串的哈希值。一個字符串的哈希值,由以下公式計算得到:
這裏寫圖片描述

Si​​ 代表 S[i] 字符的 ASCII 碼。
請幫助度熊計算大字符串中任意一段的哈希值是多少。

Output
對於每一個詢問,輸出一個整數值,代表大字符串從 aa 位到 bb 位的子串的哈希值。

Sample Input
Copy
2
ACMlove2015
1 11
8 10
1
testMessage
1 1
Sample Output
6891
9240
88

分析:
本題最直接的思路是直接計算每次的hash值,但是需要對每組String內輸入的a和b都需要從a 位置計算到b 位置,系統會顯示TLE, 所以,這裏需要用到乘法逆元(具體請自行百度)。

java代碼如下:

package bestcoder;

import java.util.Scanner;
//
public class HashOfString {
    public int maxLen = 1000001;
    public int inv[] = new int [maxLen];
    public int re[] = new int [maxLen];
    public int allHash[];
    public int mod = 9973;

    public static void main(String args[]) {
        HashOfString m = new HashOfString();
        m.getInput();
    }

    public void getInput() {
        Scanner cin = new Scanner(System.in);
        while (cin.hasNext()) {
            int T = cin.nextInt();
            String str = cin.next();
            getArray(str);
            for (int i = 1; i <= T; i++) {
                int a = cin.nextInt();
                int b = cin.nextInt();

                int num = getNum(a , b);
                System.out.println(num);
            }
        }
        cin.close();
    }
    public void getArray(String str){
        inv[1]=1;  
        for(int i=2;i<maxLen;++i)  
        {  
            inv[i]=inv[mod%i]*(mod-mod/i)%mod;  
        } 

        allHash = new int[str.length() + 1];
        allHash[0] = 1;
        re[0] = 1;
        char[] ch = str.toCharArray();
        for(int i = 0; i < ch.length; i++){
            int num = ch[i];
            allHash[i + 1] = allHash[i] * (num - 28);
            allHash[i+1] %= mod;
            re[i + 1] = inv[allHash[i + 1]];
        }
    }

    public int getNum(int a, int b) {
        return (allHash[b]*re[a-1]) % mod ;
    }
}

Problem B:
Problem Description
度熊面前有一個全是由1構成的字符串,被稱爲全1序列。你可以合併任意相鄰的兩個1,從而形成一個新的序列。對於給定的一個全1序列,請計算根據以上方法,可以構成多少種不同的序列。

Input
這裏包括多組測試數據,每組測試數據包含一個正整數NN,代表全1序列的長度。

1\leq N \leq 2001≤N≤200

Output
對於每組測試數據,輸出一個整數,代表由題目中所給定的全1序列所能形成的新序列的數量。

Sample Input
1
3
5
Sample Output
1
3
8

Hint

如果序列是:(111)。可以構造出如下三個新序列:(111), (21), (12)。

AC 的Java代碼如下:

package bestcoder;

import java.math.BigInteger;
import java.util.Scanner;
//斐波那契堆1~200
//由於當N較大時(如N=200時),所得的結果會超過Integer和Long,所以本題求解需要用到BigInteger
public class FibonacciHeap {
    int max = 201;
    BigInteger [] fun = new BigInteger[max];

    public static void main(String args[]) {
        FibonacciHeap m = new FibonacciHeap();
        m.getInput();
    }

    public void getInput() {
        Scanner cin = new Scanner(System.in);
        getSequence();
        while (cin.hasNext()) {
                int N = cin.nextInt();
                if(N >= 1 && N <= 200)
                    System.out.println(fun[N]);
                else 
                    System.out.println();

        }
        cin.close();
    }
    public void getSequence(){
        fun[0] = new BigInteger("1");
        fun[1] = new BigInteger("1");
        for(int i = 2; i < max; i++){
            fun[i] = (fun[i - 1]).add( fun[i - 2]);
        }
    }
}

Problem C: 神奇字典
Problem Description
度熊手上有一本神奇的字典,你可以在它裏面做如下三個操作:

1、insert : 往神奇字典中插入一個單詞

2、delete: 在神奇字典中刪除所有前綴等於給定字符串的單詞

3、search: 查詢是否在神奇字典中有一個字符串的前綴等於給定的字符串
Input
這裏僅有一組測試數據。第一行輸入一個正整數N (1\leq N\leq 100000)N(1≤N≤100000),代表度熊對於字典的操作次數,接下來NN行,每行包含兩個字符串,中間中用空格隔開。第一個字符串代表了相關的操作(包括: insert, delete 或者 search)。第二個字符串代表了相關操作後指定的那個字符串,第二個字符串的長度不會超過30。第二個字符串僅由小寫字母組成。

Output
對於每一個search 操作,如果在度熊的字典中存在給定的字符串爲前綴的單詞,則輸出Yes 否則輸出 No。

Sample Input
5
insert hello
insert hehe
search h
delete he
search hello
Sample Output
Yes
No

AC的java代碼:

package bestcoder;

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

//神奇詞典
//用TrieTree 來解決本題
public class Main {
    Word root = new Word('@');//總目錄,它的子節點爲詞典所有單詞的首字母
    public static void main(String args[]) {
        Main m = new Main();
        m.getInput();
    }

    public void getInput() {
        Scanner cin = new Scanner(System.in);
        while (cin.hasNext()) {
            int N = cin.nextInt();
            for (int i = 0; i < N; i++) {
                String option = cin.next();//操作,用String來保存
                String str = cin.nextLine();//單詞,用String來保存
                Order(option, str);
            }
            break;
        }
        cin.close();
    }

    //根據輸入,找到對應的命令:insert,delete,search
    public void Order(String opt, String str) {
        char[] charArray = str.toCharArray();//將單詞字符串轉化爲字符數組
        switch (opt) {
        case "insert": {
            insertTrieTree(charArray);
            break;
        }
        case "delete": {
            delTrieTree(charArray);
            break;
        }
        case "search": {
            searchTrieTree(charArray);
            break;
        }
        default: {
//          System.out.println();
            break;
        }
        }
    }

    //刪除操作 delete str:刪除以str爲前綴的“單詞”
    public void delTrieTree(char[] cc) {
        int count = 0;
        Word pa = root;
        if (root.ch.containsKey(cc[0])) {
            Word w = root.ch.get(cc[0]);
            int i = 0;
            for (i = 1; i < cc.length; i++) {
                if (w.ch.containsKey(cc[i])) {
                    pa = w;
                    w = w.ch.get(cc[i]);
                } else
                    break;
            }
            if (i == cc.length) {
                count = w.num;
                pa.ch.remove(cc[i-1]);
                w.ch.clear();

                w = root.ch.get(cc[0]);
                for (i = 1; i < cc.length; i++) {
                        w.num -= count;
                        w = w.ch.get(cc[i]);
                }
            }
        }

    }

    //查找
    public void searchTrieTree(char[] cc) {
        if (root.ch.containsKey(cc[0])) {
            Word w = root.ch.get(cc[0]);
            int i = 0;
            for (i = 1; i < cc.length; i++) {
                if (w.ch.containsKey(cc[i])) {
                    w = w.ch.get(cc[i]);
                } else
                    break;
            }
            if (i == cc.length && w.num > 0)
                System.out.println("Yes");
            else
                System.out.println("No");
        } else
            System.out.println("No");
    }

    //插入
    public void insertTrieTree(char[] cc) {
        if (!root.ch.containsKey(cc[0])) {
            root.ch.put(cc[0], new Word(cc[0]));
        }
        root.ch.get(cc[0]).num++;
        Word w = root.ch.get(cc[0]);
        for (int i = 1; i < cc.length; i++) {
            if (!w.ch.containsKey(cc[i])) {
                w.ch.put(cc[i], new Word(cc[i]));
            }
            w = w.ch.get(cc[i]);
            w.num++;
        }
    }
}

class Word {
    char c;
    int num = 0;
    public Word(char c) {
        this.c = c;
    }
    Map<Character, Word> ch = new HashMap<Character, Word>();
}

Problem D: 人名統計
Problem Description
度熊所居住的 D 國,是一個完全尊重人權的國度。以至於這個國家的所有人命名自己的名字都非常奇怪。一個人的名字由若干個字符組成,同樣的,這些字符的全排列的結果中的每一個字符串,也都是這個人的名字。例如,如果一個人名字是 ACM,那麼 AMC, CAM, MAC, MCA, 等也都是這個人的名字。在這個國家中,沒有兩個名字相同的人。

度熊想統計這個國家的人口數量,請幫助度熊設計一個程序,用來統計每一個人在之前被統計過多少次。

Input
這裏包括一組測試數據,第一行包含一個正整數NN,接下來的NN 行代表了 NN 個名字。NN 不會超過100,000100,000,他們的名字不會超過40位.

Output
對於每輸入的一個人名,輸出一個整數,代表這個人之前被統計了多少次。

Sample Input
5
ACM
MAC
BBA
ACM
BAB
Sample Output
0
1
0
2
1
AC的java代碼如下:

package bestcoder;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
//百度之星挑戰賽:Problem D: 一個人的名字由若干個字符組成,同樣的,這些字符的全排列的結果中的每一個字符串,也都是這個人的名字。
//例如,如果一個人名字是 ACM,那麼 AMC, CAM, MAC, MCA, 等也都是這個人的名字
public class SameNamePermutation {

    Map<String, Integer> map = new HashMap<String, Integer>();;

    public static void main(String args[]) {
        SameNamePermutation m = new SameNamePermutation();
        m.getInput();
    }

    public void getInput() {
        Scanner cin = new Scanner(System.in);
        while (cin.hasNext()) {
            int T = cin.nextInt();
            for (int i = 1; i <= T; i++) {
                String str = cin.next();
                int num = getNum(str);
                System.out.println(num);
            }
        }
        cin.close();
    }

    public int getNum(String str) {
        int num = 0;
        str = insertSort(str);//對字符串進行排序
        if(map.containsKey(str)){
            map.put(str, map.get(str) + 1);
            num = map.get(str);
        }
        else{
            map.put(str,0);
            num = 0;
        }
        return num;
    }
    public String insertSort(String str){
        char[] ch = str.toCharArray();
        /*for(int i = 1; i < ch.length; i++){
            char tmp = ch[i];
            int j = 0;
            for(j = i; j > 0 && tmp < ch[j - 1]; j--){
                ch[j] = ch[j-1];
            }
            ch[j] = tmp;
        }*/
        Arrays.sort(ch);
        String s = Arrays.toString(ch);
        return s;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章