https://ac.nowcoder.com/acm/contest/4370/B
签到题吧 时限给的足足有5s 所以可以直接用stl里的unordered_map
把每个字符串的前缀塞进去,最后遍历一下看是不是有某个字符串塞进去了两次即可
复杂度 t * n * len *log unordered_map本质是哈希表,是可以卡掉的
如果时限给的比较紧,字典树即可
考虑把每个字符串都插入字典树 全部插入后,遍历所有字符串,看过程中的字符是不是存在,以及结尾位置是不是≥2(即存在两个相同字符串) 复杂度t * n * len
下面给出unordered_map和字典树版本的代码
unordered_map:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
string s[250005];
int main()
{
ios::sync_with_stdio(0);
int t;cin>>t;
int cas=0;
while(t--){
int n;cin>>n;
unordered_map<string,int> mp;
int flag=0;
for(int i=0;i<n;i++){
cin>>s[i];
int len=s[i].size();
string c="";
for(int j=0;j<len;j++){
c+=s[i][j];
mp[c]++;
}
}
for(int i=0;i<n;i++) if(mp[s[i]]>=2) {flag=1;break;}
cout<<"Case #"<<++cas<<": ";
cout<<(flag?"No":"Yes")<<endl;
}
return 0;
}
字典树:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m;
int trie[100005][10];
int val[100005];
char c[10005][15];
int tot;
void insert(int x)
{
int root=0;
int len=strlen(c[x]);
for(int i=0;i<len;i++)
{
int id=c[x][i]-'0';
if(!trie[root][id]) trie[root][id]=++tot;
root=trie[root][id];
}
val[root]++;
}
bool query(int x)
{
int root=0;
int len=strlen(c[x]);
for(int i=0;i<len;i++)
{
int id=c[x][i]-'0';
if(val[root]) return 1;
root=trie[root][id];
}
if(val[root]>=2) return 1;
return 0;
}
int main()
{
int cas;
scanf("%d",&cas);
for(int tt=1;tt<=cas;tt++)
{
tot=0;
scanf("%d",&n);
memset(trie,0,sizeof trie);
memset(val,0,sizeof val);
for(int i=0;i<n;i++)
{
scanf("%s",c[i]);
insert(i);
}
printf("Case #%d: ",tt);
int flag=0;
for(int i=0;i<n;i++)
{
flag=query(i);
if(flag) break;
}
if(!flag) puts("Yes");
else puts("No");
}
return 0;
}