题目大意:
题目链接:https://www.luogu.org/problemnew/show/P2580
先给出个字符串,之后再给出个串,若在那个字符串中出现过且在串中第一次出现,输出"OK",如果出现在串单在串中出现过,输出"REPEAT",如果没有出现在串输出。
思路:
这道题正解是,当然如果你想用的做也没有人拦你。
首先将前个串插入到里,之后读入的个串就在字典树里查找,如果找到并且是第一次出现,那么就返回"OK",否则返回"REPEAT",如果根本找不到或就返回"WRONG"。
用的话就将前个串放进数组,然后每读入一个串就在数组里查找。跟字典树思路是基本一样的。
代码:
:
#include <cstdio>
#include <string>
#include <iostream>
#define N 300000
using namespace std;
int n,trie[N+1][31],num;
string read;
bool end[N+1],sum[N+1];
void Insert(string s) //插入
{
int p=1;
for (int i=0;i<s.size();i++)
{
if (!trie[p][s[i]-'a'+1]) //没有这个点
trie[p][s[i]-'a'+1]=++num; //新建节点
p=trie[p][s[i]-'a'+1]; //继续搜
}
end[p]=true; //记录
return;
}
string find (string s) //查找
{
int p=1;
for (int i=0;i<s.size();i++)
if (!(p=trie[p][s[i]-'a'+1])) return "WRONG"; //找不到这个串
if (!end[p]) return "WRONG"; //找到但是没有在这里结束就退出
//就像n串有一个abcde,m串有一个abc,你能在Trie里找到abc,但是实际上是abcde的一部分,不算找到。
if (!sum[p]) //找到且为第一次
{
sum[p]=true;
return "OK";
}
return "REPEAT"; //多次,之前找到过
}
int main()
{
scanf("%d\n",&n);
for (int i=1;i<=n;i++)
{
cin>>read;
Insert(read);
}
scanf("%d\n",&n);
for (int i=1;i<=n;i++)
{
cin>>read;
cout<<find(read)<<endl;
}
return 0;
}
:
#include <cstdio>
#include <string>
#include <map>
#include <iostream>
using namespace std;
string s;
int n;
map<string,int> a; //map
int main()
{
cin>>n;
for (int i=1;i<=n;i++)
{
cin>>s;
a[s]=1; //记录,类似hash
}
cin>>n;
for (int i=1;i<=n;i++)
{
cin>>s;
if (a[s]==1)
{
puts("OK");
a[s]=2;
}
else if (a[s]==2)
{
puts("REPEAT");
}
else puts("WRONG");
}
return 0;
}