2016年第七屆藍橋杯Java程序設計本科B組決賽 鹼基(編程大題)

2016年第七屆藍橋杯Java程序設計本科B組決賽個人題解彙總:

https://blog.csdn.net/daixinliangwyx/article/details/90169154

 

第五題

標題:鹼基

交題測試地址:https://www.dotcpp.com/oj/problem1835.html

生物學家正在對n個物種進行研究。
其中第i個物種的DNA序列爲s[i],其中的第j個鹼基爲s[i][j],鹼基一定是A、T、G、C之一。
生物學家想找到這些生物中一部分生物的一些共性,他們現在關注那些至少在m個生物中出現的長度爲k的連續鹼基序列。準確的說,科學家關心的序列用2m元組(i1,p1,i2,p2....im,pm)表示,
滿足:
1<=i1<i2<....<im<=n;
且對於所有q(0<=q<k), s[i1][p1+q]=s[i2][p2+q]=....=s[im][pm+q]。

現在給定所有生物的DNA序列,請告訴科學家有多少的2m元組是需要關注的。如果兩個2m元組有任何一個位置不同,則認爲是不同的元組。

【輸入格式】
輸入的第一行包含三個整數n、m、k,兩個整數之間用一個空格分隔,意義如題目所述。
接下來n行,每行一個字符串表示一種生物的DNA序列。
DNA序列從1至n編號,每個序列中的鹼基從1開始依次編號,不同的生物的DNA序列長度可能不同。

【輸出格式】
輸出一個整數,表示關注的元組個數。
答案可能很大,你需要輸出答案除以1000000007的餘數。

【樣例輸入】
3 2 2
ATC
TCG
ACG

【樣例輸出】
2

再例如:
【樣例輸入】
4 3 3
AAA
AAAA
AAA
AAA

【樣例輸出】
7


【數據規模與約定】
對於20%的數據,k<=5,所有字符串總長L滿足L <=100
對於30%的數據,L<=10000
對於60%的數據,L<=30000
對於100%的數據,n<=5,m<=5,1<=k<=L<=100000
保證所有DNA序列不爲空且只會包含’A’ ’G’ ’C’ ’T’四種字母

資源約定:
峯值內存消耗 < 256M
CPU消耗  < 1000ms

請嚴格按要求輸出,不要畫蛇添足地打印類似:“請您輸入...” 的多餘內容。

所有代碼放在同一個源文件中,調試通過後,拷貝提交該源碼。
注意:不要使用package語句。不要使用jdk1.7及以上版本的特性。
注意:主類的名字必須是:Main,否則按無效代碼處理。


解法:題目意思要好好理解一下,就是求有多少種DNA序列組合,在每種組合中,每個DNA序列都包含了同一個k長連續鹼基序列子串(同一DNA序列中子串位置不一樣的幾種不會只算做一種,具體看下面樣例2的解釋)。

比如樣例1:這2種組合是(1,2)、(2,3):1串的TC和2串的TC、2串的CG跟3串的CG。

再比如樣例2:這7種組合是(1,2,3)、(1,2,4)、(1,3,4)、(1,2,3)、(1,2,4)、(2,3,4)、(2,3,4),具體解釋一下這7種,至於這裏面重復的組合,是因爲k長相同子串在某個串裏面的位置不一樣:

(1,2,3):1串的"AAA",2串[0,3]位置的"AAA",3串的"AAA";

(1,2,3):1串的"AAA",2串[1,4]位置的"AAA",3串的"AAA";

(1,2,4):1串的"AAA",2串[0,3]位置的"AAA",4串的"AAA";

(1,2,4):1串的"AAA",2串[1,4]位置的"AAA",4串的"AAA";

(2,3,4):2串[0,3]位置的"AAA",3串的"AAA",4串的"AAA";

(2,3,4):2串[1,4]位置的"AAA",3串的"AAA",4串的"AAA";

(1,3,4):1串的"AAA",3串的"AAA",4串的"AAA"。

做起來的話,n和m的範圍都很小,暴搜就行了,先搜出m個DNA序列,然後取這m箇中的第一個DNA序列遍歷找k長的子串,看後面m-1個DNA序列是否都包含這個子串,進行統計即可。

代碼:

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;

public class Main {
    public static InputReader in = new InputReader(new BufferedInputStream(System.in));
    public static PrintWriter out = new PrintWriter(System.out);
    public static int n, m, k;
    public static long ans, tmp, mod = 1000000007;
    public static String str;
    public static String[] s = new String[10];
    public static int[] a = new int[10];

    public static void main(String[] args) {
        n = in.nextInt();
        m = in.nextInt();
        k = in.nextInt();
        for (int i = 1; i <= n; i++)
            s[i] = in.nextLine();
        ans = 0;
        dfs(1, 1);
        out.println(ans%mod);
        out.flush();
        out.close();
    }

    static void dfs(int kk, int p) {
        if (kk > m) {
            int len = s[a[1]].length();
            for (int i = 0; i < len-k+1; i++) {
                str = s[a[1]].substring(i, i+k);
                tmp = 1;
                for (int j = 2; j <= m; j++) {
                    tmp = (tmp * getStrCount(s[a[j]], str)) % mod;
                    if (tmp == 0) break;//這些DNA序列裏遇到有不包含str子序列的,後面的DNA序列就不需要繼續查找了,直接break
                }
                ans = (ans + tmp) % mod;
            }
            return;
        }
        for (int i = p; i <= n; i++) {
            a[kk] = i;
            dfs(kk+1, i+1);
        }
    }

    static long getStrCount(String s1, String s2) {
        long sum = 0;
        String tmps = s1;
        int index = tmps.indexOf(s2);
        while (index != -1) {
            sum++;
            tmps = tmps.substring(index+1);
            index = tmps.indexOf(s2);
        }
        return sum;
    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public String nextLine() {
            String str = null;
            try {
                str = reader.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

        public Double nextDouble() {
            return Double.parseDouble(next());
        }

        public BigInteger nextBigInteger() {
            return new BigInteger(next());
        }

        public BigDecimal nextBigDecimal() {
            return new BigDecimal(next());
        }

    }
}

評測結果:

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