POJ 3630 Phone List 解题报告 字典树
解题思路:建一个字典树再进行判断就行了。详情见代码,据说用malloc分配空间会超时?这里用的静态数组。调bug调了我半天,千万注意指针的初始化。
#include<iostream>
#include<math.h>
#include<iomanip>
#include<algorithm>
#include<iostream>
#include<math.h>
#include<iomanip>
#include<algorithm>
#include<queue>
#include<cstring>
#include<string>
#include<map>
#include<stack>
#include<stdio.h>
#include<cstdio>
#include<stdlib.h>
#include<fstream>
#include<iomanip>
#pragma warning(disable:4996)
#define INF 0x3f3f3f3f
#define ll long long
#define PI acos(-1.0)
const int N = 1000010;
const int maxn = 1e9;
using namespace std;
int cnt, n;
int judge;
struct node {
int flag;
node* next[10];
}a[100000];
void build(node* t, char str[])
{
int len = strlen(str);
for (int i = 0; i < len; i++)
{
if (t->next[str[i] - '0'] == NULL)
{
cnt++;
node* tem = &a[cnt];
for (int i = 0; i < 9; i++)
{
tem->next[i] = NULL;
}
if (i == len - 1)
tem->flag = 2;//标记结尾
else
tem->flag = 1;//标记已到达过该节点
t->next[str[i] - '0'] = tem;
if (i == len - 1)
return;//如果结尾处数字是新建的,直接返回
}
t = t->next[str[i] - '0'];
if (t->flag == 2)//如果是之前某串数字的结尾,说明前缀重复了
judge = 1;
if (i == len - 1)//如果结尾处数字不是新建的,说明前缀重复了
judge = 1;
}
}
int main()
{
int t;
scanf("%d", &t);
char ch[15] = "";
while (t--)
{
judge = 0;
memset(a, 0, sizeof(a));
cnt = 0;
scanf("%d", &n);
node* temp = &a[0];//初始化头指针
for (int i = 0; i < 9; i++)
{
temp->next[i] = NULL;
}
temp->flag = 0;
for (int i = 0; i < n; i++)
{
scanf("%s", &ch);
if (judge)
continue;
build(temp, ch);
memset(ch, 0, sizeof(ch));
}
if (judge)
{
printf("NO\n");
}
else
{
printf("YES\n");
}
}
}