洛谷 P2580 【因而他錯誤的點名開始了】題解

XS中學化學競賽組教練是一個酷愛爐石的人。

他會一邊搓爐石一邊點名以致於有一天他連續點到了某個同窗兩次,而後正好被路過的校長髮現了而後就是一頓歐拉歐拉歐拉(詳情請見已結束比賽CON900)。
題目背景
這以後校長任命你爲特派探員,天天記錄他的點名。校長會提供化學競賽學生的人數和名單,而你須要告訴校長他有沒有點錯名。(爲何不直接不讓他玩爐石。)
題目描述
第一行一個整數 n,表示班上人數。接下來 n 行,每行一個字符串表示其名字(互不相同,且只含小寫字母,長度不超過 50)。第 n+2 行一個整數 m,表示教練報的名字。接下來 m 行,每行一個字符串表示教練報的名字(只含小寫字母,且長度不超過 50)。
輸入格式
對於每一個教練報的名字,輸出一行。若是該名字正確且是第一次出現,輸出「OK」,若是該名字錯誤,輸出「WRONG」,若是該名字正確但不是第一次出現,輸出「REPEAT」。(均不加引號)
輸出格式
5  
a
b
c
ad
acd
3
a
a
e
輸入樣例
OK
REPEAT
WRONG
輸出樣例
對於 40%的數據,n≤1000,m≤2000;

對於 70%的數據,n≤10000,m≤20000;

對於 100%的數據, n≤10000,m≤100000
數據範圍

一道trie樹水題。。。。。ios

一開始數組開小了,還覺得是trie樹寫炸了數組

而後抱着試一試的想法改了一下數組大小ide

而後就AC了。。。spa

#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>

using namespace std;

map <string ,int > flag;
int trie[1000100][51];
string s;//輸入用的字符串 
int tot=0;//當前是哪一個編號 

void insert()
{
    int len=s.length();
    int root=0;
    for(int i=0;i<len;i++)//挨個放置 
    {
        int id=s[i]-'a';
        if(!trie[root][id])//不存在這個節點 
        {
            trie[root][id]=++tot;//放置,標號 
        }
        root=trie[root][id];//而後繼續向下找 
    }
}

bool find()
{
    int len=s.length();
    int root=0;
    for(int i=0;s[i];i++)
    {
        int x=s[i]-'a';
        if(trie[root][x])
        {
            root=trie[root][x];//有這個節點,也就是匹配上了 
        }
        else
        return false;//沒有配上,直接結束 
    }
    return true;//匹配上 
}

int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>s;
        insert();
    }
    int m;
    cin>>m;
    for(int i=1;i<=m;i++)
    {
        cin>>s;
        if(find()&&flag[s]==0)//匹配上且第一次出現 
        {
            flag[s]=1;
            cout<<"OK"<<endl;
        }
        else if(flag[s]!=0&find())//匹配上但不是第一次出現 
        {
            cout<<"REPEAT"<<endl;
        }
        else//沒有匹配上 
        {
            cout<<"WRONG"<<endl;
        }
    }
    return 0;
}
AC代碼
相關文章
相關標籤/搜索