洛谷题单指南-字符串-P2580 于是他错误的点名开始了

原题链接:https://www.luogu.com.cn/problem/P2580

题意解读:给n个字符串,再依次处理m个字符串,对于每个字符串,如果在前面n个字符串中输出OK,如果不在n个字符串中输出WRONG,如果在n个字符串中且不止一次查询过输出REPEAT。

解题思路:

1、set/map

方法很简单直接,用set存下前n个字符串, map记录后m个字符串每个字符串出现次数,然后一一遍历m个字符串去set里查找,如果找到就再到map里判断查找过的次数。

100分代码:

#include <bits/stdc++.h>
using namespace std;

int n, m;
set<string> a;
map<string, int> b;

int main()
{
    cin >> n;
    string str;
    while(n--) 
    {
        cin >> str;
        a.insert(str);
    }
    cin >> m;
    while(m--)
    {
        cin >> str;
        b[str]++;
        int ac = a.count(str), bc = b[str];
        if(ac > 0 && bc > 1) cout << "REPEAT" << endl;
        else if(ac > 0) cout << "OK" << endl;
        else cout << "WRONG" << endl;
    }
    return 0;
}

2、Trie树

将n个姓名全部存入Trie树,对于后m个姓名,每个姓名都在Trie树中查找,判断是否存在,如果存在同时记录已经查找过的次数。

100分代码:

#include <bits/stdc++.h>
using namespace std;

const int N = 10000 * 50 + 5;
int n, m;
int son[N][26], idx, cnt[N], query[N];

void add(string str)
{
    int u = 0;
    for(int i = 0; i < str.size(); i++)
    {
        int v = str[i] - 'a';
        if(son[u][v] == 0) son[u][v] = ++idx;
        u = son[u][v];
    }
    cnt[u]++;
}

bool find(string str)
{
    int u = 0;
    for(int i = 0; i < str.size(); i++)
    {
        int v = str[i] - 'a';
        if(son[u][v] == 0) 
        {
            cout << "WRONG" << endl;
            return false;
        } 
        u = son[u][v];
    }
    if(cnt[u]) 
    {
        cout << (query[u] > 0 ? "REPEAT" : "OK") << endl;
        query[u]++;
    }   
    else cout << "WRONG" << endl;
    return true;
}

int main()
{
    cin >> n;
    string str;
    while(n--) 
    {
        cin >> str;
        add(str);
    }
    cin >> m;
    while(m--)
    {
        cin >> str;
        find(str);
    }
    return 0;
}

 

posted @ 2024-10-10 18:32  五月江城  阅读(5)  评论(0编辑  收藏  举报