- 论坛徽章:
- 0
|
题目地址:http://www.soj.me/1426
删除不用递归还真不知道怎么搞,重新写了一下,AC了,谢谢2楼~还是没人说怎么结贴啊,杯具
顺便贴下自己的代码,也希望各位帮看看还可以怎么改进- #include <stdio.h>
- #include <stdlib.h>
- #include<string.h>
- /*
- 只是对一些号码进行处理,0-9的一些组合,,刚好串最长可以是10,定义MAX=10
- */
- #define MAX 10
- typedef struct trie_node
- {
- struct trie_node *nxt[MAX];//每个节点有MAX个孩子,trie的空间开支巨大
- int mrk;//初始化为0,一个号码插入完整后置1,表示整个号码都插入trie了
- } trie_node;
- int insert(trie_node *root, char *number)
- {
- if(root==NULL)
- return 0;
- trie_node *cur = root;
- int prefix = 0, i, len=strlen(number);
- for(i=0; i<len; i++)
- {
- /*
- 因为是判断是否有前缀,先要判断mrk是不是等于1了
- 当前节点的number[i]-'0'分支为NULL
- */
- if(cur->mrk != 1 && cur->nxt[number[i]-'0']==NULL)
- {
- //分配一个新结点并初始化,插入
- cur->nxt[number[i]-'0'] = malloc(sizeof(trie_node));
- cur->nxt[number[i]-'0']->mrk = 0;
- memset(cur->nxt[number[i]-'0']->nxt, 0, sizeof(cur->nxt[number[i]-'0']->nxt));
- }
- /*
- 如果已经到号码尾部:比如先插入111,再插入11111
- 或要插入串已经到结尾:比如先插入11111,再插入111
- 表明有前缀存在
- */
- else if(cur->mrk==1 || i==len-1)
- {
- prefix = 1;
- break;
- }
- cur = cur->nxt[number[i]-'0'];
- }
- if(prefix==1)
- return 1;
- cur->mrk = 1;
- return 0;
- }
- void clr(trie_node *root)
- {
- if(root==NULL)
- return;
- int i;
- for(i=0; i<MAX; i++)
- clr(root->nxt[i]);
- free(root);
- }
- int main()
- {
- int t;
- scanf("%d", &t);
- for(; t>0; t--)
- {
- trie_node *root = malloc(sizeof(trie_node));
- root->mrk = 0;
- memset(root->nxt, 0, sizeof(root->nxt));
- int n,i, prefix = 0;
- char numbers[10000][MAX];
- scanf("%d", &n);
- for(i=0; i<n; i++)
- scanf("%s", numbers[i]);
- for(i=0; i<n; i++)
- {
- prefix=insert(root, numbers[i]);
- if(prefix)
- break;
- }
- printf("%s\n", prefix==1?"NO":"YES");
- clr(root);
- }
- return 0;
- }
复制代码 |
|