题目大意:
输入多串数字串,要求判断是否有的数字串是其它串的前缀。如果存在输出NO,否则输出YES。
解题思路:
用trie建立字典树,然后在每个数字串的结尾处标志1,之后每输入一个串,就判断一下。是否有之前的标志记号。
#include<iostream>
#include<malloc.h>
#include<cstring>
#include<cstdio>
using namespace std;
const int MAX_LEN = 11;
typedef struct trie
{
trie *next[10];
int num;
}T;
T *tree;
bool flag;
void trieDel(T *p){
for(int i=0;i<10;i++){
if(p->next[i]!=NULL) trieDel(p->next[i]);
}
free(p);
}
void trieInsert(char str[]){
T *p=tree,*q;
int len=strlen(str);
for(int i=0;i<len;i++){
int id=str[i]-'0';
if(p->next[id]==NULL){
q=new T;
for(int j=0;j<10;j++)
q->next[j]=NULL;
q->num=0;
p->next[id]=q;
p=p->next[id];
}
else p=p->next[id];
if(p->num == 1) flag =false;
}
p->num=1;
for(int i=0;i<10;i++){
if(p->next[i]!=NULL){
flag=false;
break;
}
}
}
void init(){
tree = new T;
for(int i=0;i<10;i++)
{
tree->next[i]=NULL;
}
}
int main()
{
int cas;
scanf("%d",&cas);
while(cas--){
flag=true;
int n;
scanf("%d",&n);
getchar();
init();
for(int i=0;i<n;i++){
char str[MAX_LEN];
gets(str);
if(!flag) continue;
trieInsert(str);
}
trieDel(tree);
if(flag) printf("YES\n");
else printf("NO\n");
}
return 0;
}
以下代码没用字典树:
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<string>
#include<queue>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cctype>
typedef unsigned long long ull;
typedef long long ll;
using namespace std;
string inp[10010];
bool solve(const string &a, const string & b){
if(a.length() > b.length())
return false;
for(unsigned i = 0; i < a.length(); ++i)
if(a[i] != b[i])
return false;
return true;
}
int main(){
int t;
cin >>t;
while(t--){
int n;
bool bol = true;
cin >> n;
for(int i = 0; i < n; ++i)
cin >> inp[i];
sort(inp, inp + n);
for(int i = 0; i < n; ++i)
if(solve(inp[i], inp[i+1]))
bol = false;
cout <<(bol?"YES":"NO") <<endl;
}
return 0;
}