1. 程式人生 > >暑假訓練-訓練8.5 KMP

暑假訓練-訓練8.5 KMP

A - 字串初步
Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu
Submit

Status
Description
The Genographic Project is a research partnership between IBM and The National Geographic Society that is analyzing DNA from hundreds of thousands of contributors to map how the Earth was populated.

As an IBM researcher, you have been tasked with writing a program that will find commonalities amongst given snippets of DNA that can be correlated with individual survey information to identify new genetic markers.

A DNA base sequence is noted by listing the nitrogen bases in the order in which they are found in the molecule. There are four bases: adenine (A), thymine (T), guanine (G), and cytosine (C). A 6-base DNA sequence could be represented as TAGACC.

Given a set of DNA base sequences, determine the longest series of bases that occurs in all of the sequences.
Input
Input to this problem will begin with a line containing a single integer n indicating the number of datasets. Each dataset consists of the following components:
A single positive integer m (2 <= m <= 10) indicating the number of base sequences in this dataset.
m lines each containing a single base sequence consisting of 60 bases.
Output
For each dataset in the input, output the longest base subsequence common to all of the given base sequences. If the longest common subsequence is less than three bases in length, display the string “no significant commonalities” instead. If multiple subsequences of the same longest length exist, output only the subsequence that comes first in alphabetical order.
Sample Input
3
2
GATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
3
GATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATACCAGATA
GATACTAGATACTAGATACTAGATACTAAAGGAAAGGGAAAAGGGGAAAAAGGGGGAAAA
GATACCAGATACCAGATACCAGATACCAAAGGAAAGGGAAAAGGGGAAAAAGGGGGAAAA
3
CATCATCATCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
ACATCATCATAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AACATCATCATTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
Sample Output
no significant commonalities
AGATAC
CATCATCAT

暴力求解即可


#include<stdio.h>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<functional>
#include<vector>
#include<iomanip>
#include<math.h>
#include<iostream>
#include<sstream>
#include<stack>
#include<set>
using namespace std;
const int MAX=65;
string Str[15],Ans;
int T,N,Len;
int main()
{
    cin.sync_with_stdio(false);
    cin>>T;
    while (T--)
    {
        cin>>N;
        for (int i=0; i<N; i++) cin>>Str[i];
        Len=-1;
        for (int l=3; l<=60; l++)
            for (int i=0; i<=60-l; i++)
            {
                bool flag=true;
                string temp=Str[0].substr(i,l);
                for (int x=1; x<N; x++)
                {
                    if (Str[x].find(temp)!=string::npos)
                        continue;
                    else
                    {
                        flag=false;
                        break;
                    }
                }
                if (flag)
                {
                    if (l>Len)
                    {
                        Ans=temp;
                        Len=l;
                    }
                    else if (l==Len) Ans=min(Ans,temp);
                }
            }
        if (Len==-1) cout<<"no significant commonalities"<<endl;
        else cout<<Ans<<endl;
    }
    return 0;
}

B - KMP入門必做-匹配
Time Limit:5000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
Submit

Status
Description
Given two sequences of numbers : a[1], a[2], …… , a[N], and b[1], b[2], …… , b[M] (1 <= M <= 10000, 1 <= N <= 1000000). Your task is to find a number K which make a[K] = b[1], a[K + 1] = b[2], …… , a[K + M - 1] = b[M]. If there are more than one K exist, output the smallest one.
Input
The first line of input is a number T which indicate the number of cases. Each case contains three lines. The first line is two numbers N and M (1 <= M <= 10000, 1 <= N <= 1000000). The second line contains N integers which indicate a[1], a[2], …… , a[N]. The third line contains M integers which indicate b[1], b[2], …… , b[M]. All integers are in the range of [-1000000, 1000000].
Output
For each test case, you should output one line which only contain K described above. If no such K exists, output -1 instead.
Sample Input
2
13 5
1 2 1 2 3 1 2 3 1 3 2 1 2
1 2 3 1 3
13 5
1 2 1 2 3 1 2 3 1 3 2 1 2
1 2 3 2 1
Sample Output
6
-1


#include<stdio.h>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<functional>
#include<vector>
#include<iomanip>
#include<math.h>
#include<iostream>
#include<sstream>
#include<stack>
#include<set>
using namespace std;
const int MAX=1000006;
int A[MAX],B[10005];
int T,N,M,Next[10005];
int main()
{
    cin.sync_with_stdio(false);
    cin>>T;
    while (T--)
    {
        cin>>N>>M;
        for (int i=1; i<=N; i++) cin>>A[i];
        for (int i=1; i<=M; i++) cin>>B[i];
        memset(Next,0,sizeof(Next));
        Next[0]=-1;
        for (int i=1; i<=M; i++)
        {
            int p=Next[i-1];
            while (p>=0&&B[p+1]!=B[i]) p=Next[p];
            Next[i]=p+1;
        }
        int k=-1;
        for (int i=1,p=0; i<=N; i++)
        {
            while (p>=0&&B[p+1]!=A[i]) p=Next[p];
            if (++p==M)
            {
                k=i-p+1;
                p=Next[p];
                break;
            }
        }
        cout<<k<<endl;
    }
    return 0;
}

C - KMP入門必做-週期
Time Limit:3000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu
Submit

Status
Description
Given two strings a and b we define a*b to be their concatenation. For example, if a = “abc” and b = “def” then a*b = “abcdef”. If we think of concatenation as multiplication, exponentiation by a non-negative integer is defined in the normal way: a^0 = “” (the empty string) and a^(n+1) = a*(a^n).
Input
Each test case is a line of input representing s, a string of printable characters. The length of s will be at least 1 and will not exceed 1 million characters. A line containing a period follows the last test case.
Output
For each s you should print the largest n such that s = a^n for some string a.
Sample Input
abcd
aaaa
ababab
.
Sample Output
1
4
3
Hint
This problem has huge input, use scanf instead of cin to avoid time limit exceed.


C:  next表示模式串如果第i位(設str[0]為第0位)與文字串第j位不匹配則要回到第next[i]位繼續與文字串第j位匹配。則模式串第1位到next[n]與模式串第n-next[n]位到n位是匹配的。
如果n%(n-next[n])==0,則存在重複連續子串,長度為n-next[n]。

#include<stdio.h>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<functional>
#include<vector>
#include<iomanip>
#include<math.h>
#include<iostream>
#include<sstream>
#include<stack>
#include<set>
using namespace std;
const int MAX=1000005;
char S[MAX],P[MAX];
int Next[MAX];
int main()
{
    cin.sync_with_stdio(false);
    while (cin>>(S+1)&&S[1]!='.')
    {
        memset(Next,0,sizeof(Next));Next[0]=-1;
        int len=strlen(S+1);
        for (int i=1;i<=len;i++)
        {
            int p=Next[i-1];
            while (p>=0&&S[p+1]!=S[i]) p=Next[p];
            Next[i]=p+1;
        }
        int ans=(len%(len-Next[len])==0)?(len/(len-Next[len])):1;
        cout<<ans<<endl;
    }
    return 0;
}

D - 匹配
Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
Submit

Status
Description
一塊花布條,裡面有些圖案,另有一塊直接可用的小飾條,裡面也有一些圖案。對於給定的花布條和小飾條,計算一下能從花布條中儘可能剪出幾塊小飾條來呢?
Input
輸入中含有一些資料,分別是成對出現的花布條和小飾條,其布條都是用可見ASCII字元表示的,可見的ASCII字元有多少個,布條的花紋也有多少種花樣。花紋條和小飾條不會超過1000個字元長。如果遇見#字元,則不再進行工作。
Output
輸出能從花紋布中剪出的最多小飾條個數,如果一塊都沒有,那就老老實實輸出0,每個結果之間應換行。
Sample Input
abcde a3
aaaaaa aa
#
Sample Output
0
3


D:

#include<stdio.h>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<functional>
#include<vector>
#include<iomanip>
#include<math.h>
#include<iostream>
#include<sstream>
#include<stack>
#include<set>
using namespace std;
const int MAX=1005;
char S[MAX],P[MAX];
int Next[MAX];
int main()
{
    cin.sync_with_stdio(false);
    while (cin>>(S+1)&&S[1]!='#')
    {
        cin>>(P+1);
        int n=strlen(S+1);
        int m=strlen(P+1);
        memset(Next,0,sizeof(Next));Next[0]=-1;
        for (int i=1;i<=m;i++)
        {
            int p=Next[i-1];
            while (p>=0&&P[p+1]!=P[i]) p=Next[p];
            Next[i]=p+1;
        }
        int ans=0;
        for (int i=1,p=0;i<=n;i++)
        {
            while (p>=0&&P[p+1]!=S[i]) p=Next[p];
            if (++p==m) {ans++;p=0;}
        }
        cout<<ans<<endl;
    }
    return 0;
}

E - 週期-迴圈
Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
Submit

Status
Description
For each prefix of a given string S with N characters (each character has an ASCII code between 97 and 126, inclusive), we want to know whether the prefix is a periodic string. That is, for each i (2 <= i <= N) we want to know the largest K > 1 (if there is one) such that the prefix of S with length i can be written as A K , that is A concatenated K times, for some string A. Of course, we also want to know the period K.
Input
The input file consists of several test cases. Each test case consists of two lines. The first one contains N (2 <= N <= 1 000 000) – the size of the string S. The second line contains the string S. The input file ends with a line, having the number zero on it.
Output
For each test case, output “Test case #” and the consecutive test case number on a single line; then, for each prefix with length i that has a period K > 1, output the prefix size i and the period K separated by a single space; the prefix sizes must be in increasing order. Print a blank line after each test case.
Sample Input
3
aaa
12
aabaabaabaab
0
Sample Output
Test case #1
2 2
3 3

Test case #2
2 2
6 2
9 3
12 4


E: 同C題 長度從1開始列舉到N

#include<stdio.h>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<functional>
#include<vector>
#include<iomanip>
#include<math.h>
#include<iostream>
#include<sstream>
#include<stack>
#include<set>
using namespace std;
const int MAX=1000005;
char S[MAX];
int N,Next[MAX];
int main()
{
    cin.sync_with_stdio(false);
    int cases=0;
    while (cin>>N&&N)
    {
        cin>>(S+1);
        memset(Next,0,sizeof(Next));Next[0]=-1;
        for (int i=1;i<=N;i++)
        {
            int p=Next[i-1];
            while (p>=0&&S[p+1]!=S[i]) p=Next[p];
            Next[i]=p+1;
        }
        cout<<"Test case #"<<++cases<<endl;
        for (int i=1;i<=N;i++)
        {
            int K=(i%(i-Next[i])==0)?(i/(i-Next[i])):1;
            if (K!=1)
                cout<<i<<' '<<K<<endl;
        }
        cout<<endl;
    }
    return 0;
}

F - Interesting
Time Limit:1000MS Memory Limit:65535KB 64bit IO Format:%I64d & %I64u
Submit

Status
Description
The shortest common superstring of 2 strings S 1 and S 2 is a string S with the minimum number of characters which contains both S 1 and S 2 as a sequence of consecutive characters. For instance, the shortest common superstring of “alba” and “bacau” is “albacau”.
Given two strings composed of lowercase English characters, find the length of their shortest common superstring.
Input
The first line of input contains an integer number T, representing the number of test cases to follow. Each test case consists of 2 lines. The first of these lines contains the string S 1 and the second line contains the string S 2. Both of these strings contain at least 1 and at most 1.000.000 characters.
Output
For each of the T test cases, in the order given in the input, print one line containing the length of the shortest common superstring.
Sample Input
2
alba
bacau
resita
mures
Sample Output
7
8


F:


#include<stdio.h>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<functional>
#include<vector>
#include<iomanip>
#include<math.h>
#include<iostream>
#include<sstream>
#include<stack>
#include<set>
using namespace std;
const int MAX=1000006;
char A[MAX],B[MAX];
int Next[MAX],T;
void getNext(char *P)
{
    int lenP=strlen(P+1);
    memset(Next,0,sizeof(Next));
    Next[0]=-1;
    for (int i=1; i<=lenP; i++)
    {
        int p=Next[i-1];
        while (p>=0&&P[p+1]!=P[i]) p=Next[p];
        Next[i]=p+1;
    }
}
int kmp(char *P,char *S)
{
    getNext(P);
    int lenP=strlen(P+1);
    int lenS=strlen(S+1);
    int i=1,p=0;
    while (i<=lenS&&p<lenP)
    {
        if (p==-1||P[p+1]==S[i]) i++,p++;
        else p=Next[p];
    }
    return p;
}
int main()
{
    cin.sync_with_stdio(false);
    cin>>T;
    while (T--)
    {
        cin>>(A+1)>>(B+1);
        int lenA=strlen(A+1);
        int lenB=strlen(B+1);
        int x1=kmp(A,B);
        int x2=kmp(B,A);
        cout<<lenA+lenB-max(x1,x2)<<endl;
    }
    return 0;
}

G - 結合dp試試orz
Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u
Submit

Status
Description
As is known to all, in many cases, a word has two meanings. Such as “hehe”, which not only means “hehe”, but also means “excuse me”.
Today, ?? is chating with MeiZi online, MeiZi sends a sentence A to ??. ?? is so smart that he knows the word B in the sentence has two meanings. He wants to know how many kinds of meanings MeiZi can express.
Input
The first line of the input gives the number of test cases T; T test cases follow.
Each test case contains two strings A and B, A means the sentence MeiZi sends to ??, B means the word B which has two menaings. string only contains lowercase letters.

Limits
T <= 30
|A| <= 100000
|B| <= |A|

Output
For each test case, output one line containing “Case #x: y” (without quotes) , where x is the test case number (starting from 1) and y is the number of the different meaning of this sentence may be. Since this number may be quite large, you should output the answer modulo 1000000007.
Sample Input
4
hehehe
hehe
woquxizaolehehe
woquxizaole
hehehehe
hehe
owoadiuhzgneninougur
iehiehieh
Sample Output
Case #1: 3
Case #2: 2
Case #3: 5
Case #4: 1

Hint

In the first case, “ hehehe” can have 3 meaings: “he”, “he”, “hehehe”.
In the third case, “hehehehe” can have 5 meaings: “hehe”, “he*he”, “hehe”, “**”, “hehehehe”.



G:  令F[i]表示到i結尾的字串可以表示的不同含義數
首先F[ i ] = F[ i - 1] ;不管 i 位置匹配不匹配,它都應該繼承前一位置的總數。
然後對於第i個位置,如果它從i-m到 第i-1個位置正好和S串匹配,則F[ i ] += F[ i -m ] ;
因為從i-m到i-1長度為m的這個串,如果它使用了第二個含意,則i-m到i-1這些位置都不能再變了,所以是加上第i-m個位置上的總數;


#include<stdio.h>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<functional>
#include<vector>
#include<iomanip>
#include<math.h>
#include<iostream>
#include<sstream>
#include<stack>
#include<set>
using namespace std;
const int MAX=100006;
const int MOD=1000000007;
char S[MAX],P[MAX];
int Next[MAX],T,lenS,lenP,Mark[MAX],F[MAX];
int main()
{
    cin.sync_with_stdio(false);
    cin>>T;
    for (int cases=1; cases<=T; cases++)
    {
        cin>>(S+1)>>(P+1);
        lenS=strlen(S+1);
        lenP=strlen(P+1);
        memset(Next,0,sizeof(Next));
        memset(F,0,sizeof(F));
        Next[0]=-1;
        for (int i=1; i<=lenP; i++)
        {
            int p=Next[i-1];
            while (p>=0&&P[p+1]!=P[i]) p=Next[p];
            Next[i]=p+1;
        }
        memset(Mark,0,sizeof(Mark));
        for (int i=1,p=0; i<=lenS; i++)
        {
            while (p>=0&&P[p+1]!=S[i]) p=Next[p];
            if (++p==lenP)
            {
                Mark[i-lenP+1]=1;
                p=Next[p];
            }
        }
        for (int i=1;i<=lenS+1;i++)
        {
            F[i]=(F[i-1]+F[i])%MOD;
            if (Mark[i])
                F[i+lenP]=(F[i+lenP]+F[i]+1)%MOD;
        }
        cout<<"Case #"<<cases<<": "<<F[lenS+1]+1<<endl;
    }
    return 0;
}

相關推薦

暑假訓練-訓練8.5 KMP

A - 字串初步 Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu Submit Status Description The Genograp

訓練總結8.5

感覺運用起來比前兩天熟練了許多,這兩天做的搜尋方式,不是原來的那麼簡單的走走,而是改變了一些搜尋的方法,也就是增設了幾個限制條件。 比如做的推冰球問題,推冰球的時候沒有碰到邊界或者障礙物的話,要一直的走,碰到障礙物後,障礙物會消失,求走到目標點的最少的步數。Blog  在做

暑假訓練-訓練8 區間DP

A - 石子歸併 Time Limit:1000MS Memory Limit:131072KB 64bit IO Format:%lld & %llu Submit Status Description 現在有n堆石子,第i堆

hdu 5381 The sum of gcd 2015多校聯合訓練賽#8莫隊算法

names 來看 efi nbsp span ems multipl script there The sum of gcd Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K

2018-暑假留校訓練賽(2)

const 思路 round art cannot cto 方程 least 只需要 題目鏈接:https://vjudge.net/contest/237052#problem/A Thanks a lot for helping Harry Potter in

2018暑假第四周總結(7.30-8.5

遊泳 好玩 如果 哪裏 暑假 沒有 程序 多少 驗證 感冒,所以並未有多少進展,只是將計算器增加了驗證功能,允許輸入小數。 對於分數放棄了,不知道輸入什麽字符。不過開根號,冪還是要加的。 感覺自己寫的計算器還是有點混亂,隨意去設置新的變量,沒有統一,再改一改。 下周要做的:

HDU-2017 多校訓練8-補題

ACM模版 今天的比賽真讓我難受,題目辣麼長,開始二十分鐘後竟然 0A0A,儼然讓我感覺自己這次要爆零,搞了倆小時依然無果,好在沒有放棄,總算是幹掉了第 1111 題,然後又成功水過第 0808 題,有些出乎我的意料了,但是好在我還是堅持到了最後,儘管止步於兩

藍橋杯 演算法訓練 ALGO-148 5-1最小公倍數

演算法訓練 5-1最小公倍數 時間限制:1.0s 記憶體限制:256.0MB 提交此題 問題描述   編寫一函式lcm,求兩個正整數的最小公倍數。 樣例輸入 3 5 樣例輸出 15 與上面的樣例輸入對應的輸出。 例: 資料規模和約定   輸入資料中每一個數的範圍。   例:兩個數都小

積跬步至千里——演算法強化訓練8)卡特蘭數相關題目求解

在程式設計之美上又看到卡特蘭數的題目,所以就把這類題目做個總結。 至此,已經遇到過得卡特蘭數的題目有: 1、12個高矮不同的人,排成兩排,每排必須是從矮到高排列,而且第二排比對應的第一排的人高,問排列方式有多少種? 解答:12個高矮不同,則可以編號1 2 3 4 5 6 7

2018.12.31 NOIP訓練 偶數個5(簡單數論)

傳送門 對於出題人 z x y o

近一個月的學習總結(4.85.12)

line spa java泛型 思想 習題 cti mysql 數組 對象 Java-se基礎知識的學習已經告一段落,對自己這一個月的知識體系做一個大致的總結: 1.Java語言基礎(基礎完成) 2.面向對象基礎(封裝、繼承、多態)(基礎完成) 3.抽象類、接口(基礎完成)

MyEclipse 8.5安裝Aptana

rgb ssa 介紹 enter path family 結構 安裝eclipse java Aptana簡單介紹 Aptana是一個很強大,開源,專註於JavaScript的Ajax開發IDE它的特性包含: 1、JavaScript,JavaScript函數,

2017.8.5 瀏覽器中圖片的加載

htm col 背景圖 計算 進行 背景 加載 布局 規則 瀏覽器加載一個html頁面: 解析html===》構建DOM樹 -----遇到img標簽加載圖片 加載樣式===》解析樣式 ===》構建樣式規則樹 -----遇到背景圖片鏈接不加載 加載

聯考8.5

建立 運動 esp ont 估算 生活 由於 ret 指數 day2的暴力分拿的還算穩,然而只會打暴力...... T1數論題, 30分暴力直接走人 T2很像一個DP,先打了暴力留著對拍,結果剛了兩個小時毛都沒寫出來,暴力也萎了...... T3最小生成樹啊,碼完krusk

2017.8.5 VMware的介紹與安裝

eight 序列號 成功 -128 而是 漢化 容易 自啟 局域網 1 VMware簡介 官網地址:http://www.vmware.com VMware的功能: 是一個虛擬PC的軟件,可以在現有的操作系統上虛擬出一個新的硬件環境,相當於模擬出一臺新的PC,以此來實

【NOIP2017模擬8.5】隊伍統計

優先級 con isp pla cnblogs noip 技術分享 freopen 100% Description 現在有n個人要排成一列,編號為1->n 。但由於一些不明原因的關系,人與人之間可能存在一些矛盾關系,具體有m條矛盾關系(u,v),表示編號

2014-8-5 noip(霧)模擬賽

子節點 圖書 忘記 scanf 拒絕 踏實 構造 過多 using 皇帝的煩惱(二分答案) Description 經過多年的殺戮,秦皇終於統一了中國。為了抵禦外來的侵略,他準備在國土邊境安置n名將軍。不幸的是這n名將軍羽翼漸豐,開始展露他們的狼子野心了。他們拒絕述職、

8.1 shell介紹 8.2 命令歷史 8.3 命令補全和別名 8.4 通配符 8.5 輸入輸出重定向

8.1 shell介紹 8.2 命令歷史 8.3 命令補全和別名 8.4 通配符 8.5 輸入輸出重定向8.1 shell介紹 8.2 命令歷史 8.3 命令補全和別名 8.4 通配符 8.5 輸入輸出重定向 # Linux shell 基礎 # 8.1 shell 介紹 - 什麽是shell 1

Lotus DominoDesigner 8.5 常見基本操作(摘抄)

文件中 插入表格 安全性 str 雙擊 寬度 輸出 匹配 rdquo Lotus DominoDesigner 8.5 常見基本操作(圖文) Lotus DominoDesigner 8.5是網頁制作工具,它是窗口加編程的合體軟件 若安裝時服務器沒響應,多半是在配置服務

8.5 類的私有變量

類的私有變量class A(object): _name=‘zhou‘ _sex=‘F‘ def hello(self): print(self._name) print(self._sex) def get_sex(self):