KMP_字符串匹配

不錯的博客
求next數組:

void GetNext(char* p,int next[])  
{  
    int pLen = strlen(p);  
    next[0] = -1;  
    int j = 0;  
    int k =next[j];  
    while (j < pLen)  //最后,next[plen]也會求出來
    {  
        //p[k]表示前綴,p[j]表示后綴  
        if (k == -1 || p[j] == p[k])   
        {  
            ++k;  
            ++j;  
            next[j] = k;  
        }  
        else   
        {  
            k = next[k];  
        }  
    }  
}

注意:求next數組得到的最長公共前綴后綴是可以重疊的:
比如:ababa,next[5]=3,前綴為aba,后綴為aba
求next數組的方法可以優化:

void GetNextval(char* p, int next[])  
{  
    int pLen = strlen(p);  
    int j = 0;  
    next[j] = -1;  
    int k = next[j];  
    while (j < pLen)  
    {  
        //p[k]表示前綴,p[j]表示后綴    
        if (k == -1 || p[j] == p[k])  
        {  
            ++j;  
            ++k;  
            //較之前next數組求法,改動在下面4行  
            if (p[j] != p[k])  
                next[j] = k;   //之前只有這一行  
            else  
                //因為不能出現p[j] = p[ next[j ]],所以當出現時需要繼續遞歸,
                //k = next[k] = next[next[k]]  
                next[j] = next[k];  
        }  
        else  
        {  
            k = next[k];  
        }  
    }  
} 

不同之處:
沒有優化的getnext函數,next數組存的是前綴和后綴的最大匹配值,而優化后的getnext函數存的是在這個基礎,進行更高效的改進。
比如abcabca
改進前最后一個字符next[7]=4,表示的是前綴和后綴最大匹配是4,即abca和abca。
改進后的next[7]=-1。這點也需要徹底搞懂,才能靈活的運用next函數。
總結一下:
在求前綴和后綴的最大匹配值時,要使用第一種,也就是未優化的算法。在運用KMP匹配字符串時,使用第二種算法,因為避免了多余的判斷,更加高效。
hihoCoder #1015
題意:
求模式串在字符串中出現的次數
題解:

#include<cstdio>
#include<cstring>
using namespace std;
char pattern[10010];
int next[10010];
char str[1000010];
void getNext()
{
    int len=strlen(pattern);
    int j=0;
    next[j]=-1;
    int k=next[j];
    while(j<len)
    {
        if(k==-1||pattern[j]==pattern[k])
        {
            ++j;++k;
            if(pattern[j]!=pattern[k]) next[j]=k;
            else next[j]=next[k];
        }
        else k=next[k];
    }
}
int getCnt()
{
    int lens=strlen(str);
    int lenp=strlen(pattern);
    getNext();
    int sum=0;
    int i=0,j=0;
    while(i<lens)
    {
        if(j==-1||str[i]==pattern[j])
        {
            j++;
            i++;
        }
        else j=next[j];
        if(j==lenp) sum++;
    }
    return sum;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%s%s",pattern,str);
        printf("%d\n",getCnt());
    }
    return 0;
}

Number Sequence
題意:
求模式串在字符串首次出現的位置(題目要求下標從1開始)

#include<cstdio>
#include<cstring>
using namespace std;
int p[10010],num[1000010],next[10010],n,m;
void getNext()
{
    int j=0;
    next[j]=-1;
    int k=next[j];
    while(j<m)
    {
        if(k==-1||p[j]==p[k])
        {
            j++;
            k++;
            if(p[j]!=p[k]) next[j]=k;
            else next[j]=next[k];
        }
        else k=next[k];
    }
}
int getIndex()
{
    getNext();
    int i=0,j=0,idx=-2;
    while(i<n)
    {
        if(j==-1||num[i]==p[j])
        {
            i++;j++;
        }
        else j=next[j];
        if(j==m)
        {
            idx=i-j;
            break;
        }
    }
    return idx;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++) scanf("%d",&num[i]);
        for(int i=0;i<m;i++) scanf("%d",&p[i]);
        printf("%d\n",getIndex()+1);
    }
    return 0;
}

剪花布條
題意:
求模式串在字符串中的不重疊的出現次數
題解:
kmp匹配時,如果發現j==plen,那么j賦為0

#include<cstdio>
#include<cstring>
using namespace std;
char str[1010],p[1010];
int next[1010],slen,plen;
void getNext()
{
    int j=0;
    next[j]=-1;
    int k=next[j];
    while(j<plen)
    {
        if(k==-1||p[j]==p[k])
        {
            k++;
            j++;
            if(p[j]!=p[k]) next[j]=k;
            else next[j]=next[k];
        }
        else k=next[k];
    }
}
int getUnReptitionCnt()
{
    getNext();
    int i=0,j=0,sum=0;
    while(i<slen)
    {
        if(j==-1||str[i]==p[j])
        {
            i++;
            j++;
        }
        else j=next[j];
        if(j==plen)
        {
            sum++;
            j=0;
        }
    }
    return sum;
}
int main()
{
    while(scanf("%s",str)!=EOF)
    {
        slen=strlen(str);
        if(str[0]=='#'&&slen==1) break;
        scanf("%s",p);
        plen=strlen(p);
        printf("%d\n",getUnReptitionCnt());
    }
    return 0;
}

Cyclic Nacklace
題意:
求字符串最小循環節
(最小循環節是不可重疊的:比如ababa:最小循環節是ab,而不是aba)
題解:
注意:求最小循環節時不可以用優化的方法求next數組

#include<cstdio>
#include<cstring>
using namespace std;
char p[100010];
int plen,next[100010];
void getNext()//求最小循環節時不可以用優化的方法求next數組
{
    int j=0;
    next[j]=-1;
    int k=next[j];
    while(j<plen)
    {
        if(k==-1||p[j]==p[k])
        {
            j++;
            k++;
            next[j]=k;
        }
        else k=next[k];
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%s",p);
        plen=strlen(p);
        getNext();
        int minRepetend=plen-next[plen];//最小循環節長度
        if(minRepetend!=plen&&plen%minRepetend==0) printf("0\n");
        else printf("%d\n",minRepetend-plen%minRepetend);
    }
    return 0;
}

Period
題意:
給出一個字符串,如果它的某個前綴可以表示為循環k次的串,求出前綴index和k(k>1)
題解:
如果i%(i-next[i])==0,那么這個[0,i-1]的字符串可以表示為循環字符串

#include<cstdio>
#include<cstring>
using namespace std;
char p[1000010];
int plen,next[1000010];
void getNext()//求最小循環節時不可以用優化的方法求next數組
{
    int j=0;
    next[j]=-1;
    int k=next[j];
    while(j<plen)
    {
        if(k==-1||p[j]==p[k])
        {
            j++;
            k++;
            next[j]=k;
        }
        else k=next[k];
    }
}
void solve()
{
    int i=2;
    getNext();
    while(i<=plen)
    {
        if(next[i]!=0&&(i%(i-next[i])==0))
        {
            printf("%d %d\n",i,i/(i-next[i]));
        }
        i++;
    }
    printf("\n");
}
int main()
{
    int cas=1;
    while(scanf("%d",&plen)!=EOF,plen)
    {
        scanf("%s",p);
        printf("Test case #%d\n",cas++);
        solve();
    }
    return 0;
}

親和串
題意:
親和串的定義是這樣的:給定兩個字符串s1和s2,如果能通過s1循環移位,使s2包含在s1中,那么我們就說s2 是s1的親和串。
題解:
將s1擴大一倍,即把s1的字符復制一遍,然后判斷s2是不是在s1中。當然,如果s1原來的大小小于s2,那s1通過循環移位也不能包含s2

#include<cstdio>
#include<cstring>
using namespace std;
char str[200010];
char p[100010];
int next[100000];
int plen,slen;
void getNext()
{
    int j=0;
    next[j]=-1;
    int k=next[j];
    while(j<plen)
    {
        if(k==-1||p[j]==p[k])
        {
            j++;
            k++;
            if(p[j]!=p[k]) next[j]=k;
            else next[j]=next[k];
        }
        else k=next[k];
    }
}
bool contains()
{
    int i=0,j=0;
    while(i<slen)
    {
        if(j==-1||str[i]==p[j])
        {
            i++;
            j++;
        }
        else j=next[j];
        if(j==plen) return true;
    }
    return false;
}
int main()
{
    while(scanf("%s",str)!=EOF)
    {
        slen=strlen(str);
        scanf("%s",p);
        plen=strlen(p);
        if(plen>slen)
        {
            printf("no\n");
            continue;
        }
        for(int i=0;i<slen;i++)
        {
            str[i+slen]=str[i];
        }
        slen<<=1;
        str[slen]=0;
        getNext();
        if(contains()) printf("yes\n");
        else printf("no\n");
    }
    return 0;
}

The Minimum Length
求最小循環節...不貼代碼了
Power Strings
題意:
也是求最小循環節了
題解:

#include<cstdio>
#include<cstring>
using namespace std;
char p[1000010];
int next[1000010];
int plen;
void getNext()
{
    int j=0;
    next[j]=-1;
    int k=next[j];
    while(j<plen)
    {
        if(k==-1||p[k]==p[j])
        {
            next[++j]=++k;
        }
        else k=next[k];
    }
}
int main()
{
    while(scanf("%s",p)!=EOF)
    {
        plen=strlen(p);
        if(plen==1&&p[0]=='.') break;
        getNext();
        if(plen%(plen-next[plen])==0) printf("%d\n",plen/(plen-next[plen]));
        else printf("1\n");
    }
    return 0;
}

Seek the Name, Seek the Fame
題意:
給定字符串,求出字符串的所有的公共前綴后綴
題解:
其實就是不斷調用next數組,以尋找更短的公共前綴后綴

#include<cstdio>
#include<cstring>
using namespace std;
char p[400010];
int next[400010];
int plen;
void getNext()
{
    int j=0;
    next[j]=-1;
    int k=next[j];
    while(j<plen)
    {
        if(k==-1||p[j]==p[k])
        {
            next[++j]=++k;
        }
        else k=next[k];
    }
}
void out(int j)
{
    if(next[j]==0) return;
    out(next[j]);
    printf("%d ",next[j]);
}
int main()
{
    while(scanf("%s",p)!=EOF)
    {
        plen=strlen(p);
        getNext();
        out(plen);
        printf("%d\n",plen);
    }
    return 0;
}

Blue Jeans
題意:
給出n個字符串,找出最長的公共子串,如果有多個,輸出字典順序最小的那個
題解:
暴力拆分第一個字符串的每一個子串(子串長度>=3),然后構造子串的next數組,然后用子串匹配每個2-n這些字符串(匹配時從長度大的子串開始),如果這n-1個字符串都可以成功匹配,那么得出答案
ps:可以通過二分最大長度的方法優化

#include<cstdio>
#include<cstring>
using namespace std;
const int LEN=60;
char str[15][65];
char cpy[65];
char ans[65];
int next[65];
void getNext(char *p,int *next,int len)
{
    int j=0;
    next[j]=-1;
    int k=next[j];
    while(j<len)
    {
        if(k==-1||p[j]==p[k])
        {
            next[++j]=++k;
        }
        else k=next[k];
    }
}
bool contains(char *str,char *p,int plen)
{
    int i=0,j=0;
    while(i<LEN)
    {
        if(j==-1||str[i]==p[j])
        {
            i++;j++;
        }
        else j=next[j];
        if(j==plen) return true;
    }
    return false;
}
int main()
{
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%s",str[i]);
        }
        bool found=false;
        memset(cpy,0,sizeof(cpy));
        ans[0]='Z';
        for(int len=60;len>=3;len--)//子串長度
        {
            if(found) break;
            for(int st=0;st+len-1<60;st++)//子串的開始坐標
            {
                for(int i=0,j=st;i<len;i++,j++)
                {
                    cpy[i]=str[1][j];
                }
                cpy[len]=0;
                getNext(cpy,next,len);
                bool allContains=true;
                for(int j=2;j<=n;j++)
                {
                    if(!contains(str[j],cpy,len))
                    {
                        allContains=false;
                        break;
                    }
                }
                if(allContains)
                {
                    found=true;
                    if(strcmp(ans,cpy)>0)//字典順序小的優先
                    {
                        strcpy(ans,cpy);
                        ans[len]=0;
                    }
                }
            }
        }
        if(found) printf("%s\n",ans);
        else printf("no significant commonalities\n");
    }
    return 0;
}

Simpsons’ Hidden Talents
題意:
給定兩個字符串s1,s2,求最長的s1前綴ss使得ss為s2的后綴,輸出該字符串和其長度。
題解:
將s1,s2合并后再求整個字符串求next數組,next[len1+len2]就是答案了;
但是next[len]可能會大于len1或大于len2,所以要不斷找更短的公共前綴后綴

#include<cstdio>
#include<cstring>
using namespace std;
char p[100010];
int next[100010];
int plen,len1,len2;
void getNext()
{
    int j=0;
    next[j]=-1;
    int k=next[j];
    while(j<plen)
    {
        if(k==-1||p[j]==p[k])
        {
            next[++j]=++k;
        }
        else k=next[k];
    }
}
int main()
{
    while(scanf("%s",p)!=EOF)
    {
        len1=strlen(p);
        scanf("%s",p+len1);
        plen=strlen(p);
        len2=plen-len1;
        getNext();
        if(next[plen]==0||next[plen]==-1)
        {
            printf("0\n");
        }
        else
        {
            while(next[plen]>len1||next[plen]>len2) plen=next[plen];
            p[next[plen]]=0;
            printf("%s %d\n",p,next[plen]);
        }
    }
    return 0;
}

Count the string
題意:
求出每個前綴在串中的出現次數的總和
題解:
求出next數組,枚舉區間的最長公共前后綴以及更短的的公共前后綴

#include<cstdio>
#include<cstring>
using namespace std;
const int MOD=10007;
char p[200010];
int next[200010];
int plen;
void getNext()
{
    int j=0;
    next[j]=-1;
    int k=next[j];
    while(j<plen)
    {
        if(k==-1||p[j]==p[k])
        {
            next[++j]=++k;
        }
        else k=next[k];
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%s",&plen,p);
        getNext();
        int sum=0;
        for(int i=1;i<=plen;i++)
        {
            sum=(sum+1)%MOD;//加上前綴str[0,i-1]本身
            int tmp=next[i];
            while(tmp)//枚舉區間的最長公共前后綴以及更短的的公共前后綴
            {
                sum=(sum+1)%MOD;
                tmp=next[tmp];
            }
        }
        printf("%d\n",sum);
    }
    return 0;
}

Substrings
題意:
找到一個子串x,滿足x或x的逆串是輸入的n個字符串的子串,求長度最大的x,輸出x的長度
題解:
其實和上面Blue Jeans那道題一樣的,對第一個字符串暴力拆分,求出它的所有子串,求出next數組,然后對剩下的n-1個字符串正序kmp或者逆序kmp就可以了

#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN=110;
char str[MAXN][MAXN];
char cpy[MAXN];
int next[MAXN];
int slen[MAXN];
void getNext(char *p,int *next,int plen)
{
    int j=0;
    next[j]=-1;
    int k=next[j];
    while(j<plen)
    {
        if(k==-1||p[j]==p[k])
        {
            j++;k++;
            if(p[j]!=p[k]) next[j]=k;
            else next[j]=next[k];
        }
        else k=next[k];
    }
}
bool contains(char *str,char *p,int slen,int plen)
{
    int i=0,j=0;
    while(i<slen)
    {
        if(j==-1||str[i]==p[j])
        {
            i++;j++;
        }
        else j=next[j];
        if(j==plen) return true;
    }
    return false;
}
bool reverContains(char *str,char *p,int slen,int plen)
{
    int i=slen-1,j=0;
    while(i>=0)
    {
        if(j==-1||str[i]==p[j])
        {
            i--;j++;
        }
        else j=next[j];
        if(j==plen) return true;
    }
    return false;
}
int main()
{
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%s",str[i]);
            slen[i]=strlen(str[i]);
        }
        int length=strlen(str[1]);
        bool found=false;
        for(int len=length;len>=1;len--)
        {
            if(found) break;
            for(int st=0;st+len-1<length;st++)
            {
                for(int i=0,j=st;i<len;i++,j++)
                {
                    cpy[i]=str[1][j];
                }
                cpy[len]=0;
                getNext(cpy,next,len);
                bool all=true;
                for(int i=2;i<=n;i++)
                {
                    if(!contains(str[i],cpy,slen[i],len))
                    {
                        if(!reverContains(str[i],cpy,slen[i],len))
                        {
                            all=false;
                            break;
                        }
                    }
                }
                if(all)
                {
                    found=true;
                    break;
                }
            };
        }
        if(found) printf("%d\n",strlen(cpy));
        else printf("0\n");
    }
    return 0;
}

Corporate Identity
題意:
求所有字符的最長公共子串

#include<stdio.h>
#include<string.h>
char str[4040][220];
int next[4040];
void getnext(char *s)
{
    int len=strlen(s);
    int j=0,k=-1;
    next[0]=-1;
    while(j<=len)
    {
        if(k==-1||s[k]==s[j])
        {
            k++;
            j++;
            next[j]=k;
        }
        else
            k=next[k];
    }
}
int kmp(char *a,char *b)
{
    int i,j;
    i=j=0;
    int n=strlen(a);
    int m=strlen(b);
    getnext(b);
    while(i<n)
    {
        if(j==-1||a[i]==b[j])
        {
            i++;
            j++;
        }
        else
            j=next[j];
        if(j==m)
            return 1;
    }
    return 0;
}
int main()
{
    int n;
    while(scanf("%d",&n),n)
    {
        int i,j,k;
        for(i=0;i<n;i++)
        {
            scanf("%s",str[i]);
        }
        int len=strlen(str[0]);
        char temp[220],ans[220]="";
        for(i=0;i<len;i++)
        {
            int cnt=0;
            for(j=i;j<len;j++)
            {
                temp[cnt++]=str[0][j];
                temp[cnt]='\0';
                int flag=0;
                for(k=1;k<n;k++)
                {
                    if(!kmp(str[k],temp))
                    {
                        flag=1;
                        break;
                    }
                }
                if(!flag)
                {
                    if(strlen(temp)>strlen(ans)||(strlen(temp)==strlen(ans)&&strcmp(temp,ans)<0))
                        memcpy(ans,temp,sizeof(temp));
                }
            }
        }
        if(strlen(ans)==0)
            printf("IDENTITY LOST\n");
        else
            printf("%s\n",ans);
    }
}

String Problem
題意:
給定一個字符串S,在S所有的字符同構字符串中,求出字典序最小的同構字符串的開始位置以及它的出現次數和字典序最大的字符串的開始位置以及它的出現次數.
題解:
顯然,當S剛好啥由循環節構成的字符串時,出現次數是循環節的個數,否則是出現次數是1,而那兩個字典序剛好可以通過最小最大表示法求出來

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAXN=1000010;
int nxt[MAXN],plen;
char p[MAXN];
void getNext()
{
    int j=0;
    nxt[j]=-1;
    int k=nxt[j];
    while(j<plen)
    {
        if(k==-1||p[j]==p[k])
        {
            nxt[++j]=++k;
        }
        else k=nxt[k];
    }
}
int getMin()
{
    int i=0,j=1,k=0;
    while(i<plen&&j<plen&&k<plen)
    {
        int tmp=p[(i+k)%plen]-p[(j+k)%plen];
        if(tmp==0) k++;
        else
        {
            if(tmp>0) i=i+k+1;
            else j=j+k+1;
            if(i==j) j++;
            k=0;
        }
    }
    return min(i,j);
}
int getMax()
{
    int i=0,j=1,k=0;
    while(i<plen&&j<plen&&k<plen)
    {
        int tmp=p[(i+k)%plen]-p[(j+k)%plen];
        if(tmp==0) k++;
        else
        {
            if(tmp>0) j=j+k+1;
            else i=i+k+1;
            if(i==j) j++;
            k=0;
        }
    }
    return min(i,j);
}
int main()
{
    while(scanf("%s",p)!=EOF)
    {
        plen=strlen(p);
        getNext();
        int len=plen-nxt[plen];
        int minIndex=getMin()+1;
        int maxIndex=getMax()+1;
        if(plen%len==0) printf("%d %d %d %d\n",minIndex,plen/len,maxIndex,plen/len);
        else printf("%d %d %d %d\n",minIndex,1,maxIndex,1);
    }
}

How many
題意:
給定n個字符串,找出不同的循環同構字符串的個數。
題解:
用最小表示法表示每個字符串,然后再用set或者排序的方法去重即可

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<set>
using namespace std;
const int MAXN=110;
char str[MAXN];
char cpy[MAXN];
int len;
int getMin(char *str)
{
    int i=0,j=1,k=0;
    while(i<len&&j<len&&k<len)
    {
        int tmp=str[(i+k)%len]-str[(j+k)%len];
        if(tmp==0) k++;
        else
        {
            if(tmp>0) i=i+k+1;
            else j=j+k+1;
            if(i==j) j++;
            k=0;
        }
    }
    return min(i,j);
}
int main()
{
    int n,index,i,j;
    set<string> ss;
    while(scanf("%d",&n)!=EOF)
    {
        ss.clear();
        while(n--)
        {
            scanf("%s",str);
            len=strlen(str);
            index=getMin(str);
            for(i=index,j=0;i<len;i++,j++)
            {
                cpy[j]=str[i];
            }
            for(i=0;j<len;j++,i++)
            {
                cpy[j]=str[i];
            }
            cpy[len]=0;
            ss.insert(cpy);
        }
        printf("%d\n",ss.size());
    }
}

Problem 1901 Period II
題意:
找出所有的p,滿足:For each prefix with length P of a given string S,if
S[i]=S[i+P] for i in [0..SIZE(S)-p-1],
題解:
其實就是next數組的應用,不斷得到更短的最長公共前綴后綴

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int MAXN=1000010;
int nxt[MAXN],plen;
char p[MAXN];
void getNext()
{
    int j=0;
    nxt[j]=-1;
    int k=nxt[j];
    while(j<plen)
    {
        if(k==-1||p[j]==p[k])
        {
            nxt[++j]=++k;
        }
        else k=nxt[k];
    }
}
int main()
{
    int t,j;
    scanf("%d",&t);
    queue<int> que;
    for(int cas=1;cas<=t;cas++)
    {
        scanf("%s",p);
        plen=strlen(p);
        getNext();
        j=plen;
        while(nxt[j]!=0&&nxt[j]!=-1)
        {
            que.push(plen-nxt[j]);
            j=nxt[j];
        }
        printf("Case #%d: %d\n",cas,que.size()+1);
        while(!que.empty())
        {
            printf("%d ",que.front());
            que.pop();
        }
        printf("%d\n",plen);
    }
}

Theme Section
題意:
給定一個字符串,找出能構成"EAEBE"形式的字符串的E的最長長度。
題解:
因為前面和后面都是E,所以容易想到next數組,然后不斷求更短的公共前綴后綴長度,再判斷中間是不是包含E就可以了,判斷的方法是next[j]是不是等于當前的E的長度

#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=1e6+10;
char p[MAXN];
char cpy[MAXN];
int nxt[MAXN];
int plen;
void getFail()
{
    int j=0;
    nxt[j]=-1;
    int k=nxt[j];
    while(j<plen)
    {
        if(k==-1||p[j]==p[k])
        {
            nxt[++j]=++k;
        }
        else k=nxt[k];
    }
}
int solve()
{
    for(int i=nxt[plen];i;i=nxt[i])
    {
        for(int j=2*i;j<=plen-i+1;j++)//不重疊
        {
            if(nxt[j]==i)
            {
                return i;
            }
        }
    }
    return 0;
}
int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%s",p);
        plen=strlen(p);
        getFail();

        printf("%d\n",solve());
    }
    return 0;
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,117評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,860評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,128評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,291評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,025評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,421評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,477評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,642評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,177評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,970評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,157評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,717評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,410評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,821評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,053評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,896評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,157評論 2 375

推薦閱讀更多精彩內容