zoukankan      html  css  js  c++  java
  • HDU1247 Hat’s Words(Trie的动态内存版本)

                    Hat’s Words

                             Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
                                    Total Submission(s): 11447    Accepted Submission(s): 4085


    Problem Description
    A hat’s word is a word in the dictionary that is the concatenation of exactly two other words in the dictionary.
    You are to find all the hat’s words in a dictionary.
     
    Input
    Standard input consists of a number of lowercase words, one per line, in alphabetical order. There will be no more than 50,000 words.
    Only one case.
     
    Output
    Your output should contain all the hat’s words, one per line, in alphabetical order.
     
    Sample Input
    a ahat hat hatword hziee word
     
    Sample Output
    ahat hatword
     
    Author
    戴帽子的
     

    【思路】

           Trie。

           对于输入字符串构造一棵Trie。枚举将字符串拆分后判断是否在Trie中存在即可。

       时间复杂度为O(n*maxl*maxl)。

           指针版不用考虑maxnode的问题。

           另外一定注意判断输入结束为scanf ()!=1。

    【代码】

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define FOR(a,b,c) for(int a=(b);a<=(c);a++)
    using namespace std;
    
    const int maxl = 201;
    const int sigmasize = 26;
    /*
    //静态分配内存版本 
    const int maxnode = 400000;
    struct Trie{
        int ch[maxnode][sigmasize];
        int val[maxnode];
        int sz;
        
        Trie() {
            sz=1;
            memset(ch[0],0,sizeof(ch[0]));
            val[0]=0;
        }
        int idx(char c) { return c-'a'; }
        void insert(char* s,int v) {
            int n=strlen(s),u=0;
            for(int i=0;i<n;i++) {
                int c=idx(s[i]);
                if(!ch[u][c]) {
                    memset(ch[sz],0,sizeof(ch[sz]));
                    val[sz]=0;
                    ch[u][c]=sz++;
                }
                u=ch[u][c];
            }
            val[u]=v;
        }
        int find(char* s) {
            int n=strlen(s),u=0; 
            for(int i=0;i<n;i++) {
                int c=idx(s[i]);
                if(!ch[u][c]) return 0;
                else u=ch[u][c];
            }
            return val[u];
        }
    }trie;
    */ 
    //动态分配内存版本 
    struct Node{
        int val;
        Node* next[sigmasize];
    };
    struct Trie{
        Node *root;
        Trie() {
            root=new Node;
            for(int i=0;i<sigmasize;i++) root->next[i]=NULL;
            root->val=0;
        }
        int idx(char c) { return c-'a'; }
        void insert(char* s,int v) {
            int n=strlen(s);
            Node* u=root;
            for(int i=0;i<n;i++) {
                int c=idx(s[i]);
                if(u->next[c]==NULL) {
                    Node* tmp=new Node;
                    tmp->val=0;
                    for(int i=0;i<sigmasize;i++) tmp->next[i]=NULL;
                    u->next[c]=tmp;
                }
                u=u->next[c];
            }
            u->val=v;
        }
        int find(char* s) {
            int n=strlen(s);
            Node* u=root;
            for(int i=0;i<n;i++) {
                int c=idx(s[i]);
                if(u->next[c]==NULL) return 0;
                else u=u->next[c];
            }
            return u->val;
        }
        void del(Node *root) {
            for(int i=0;i<sigmasize;i++) {
                if(root->next[i]!=NULL) del(root->next[i]);
            }
            free(root);
        }
    }trie;
    
    int n=0;
    char s[50010][maxl];
    
    int main() {
        //freopen("cin.in","r",stdin);
        //freopen("cout.out","w",stdout);
        while(scanf("%s",s[n])==1)    // 注意是scanf==1判断 
        {
            trie.insert(s[n],1);
            n++;
        }
        char t1[maxl],t2[maxl];
        FOR(i,0,n-1)
        {
            int len=strlen(s[i]);
            FOR(j,1,len-1) {
                strcpy(t1,s[i]);
                t1[j]='';
                strcpy(t2,s[i]+j);
                if(trie.find(t1) && trie.find(t2)) {
                    printf("%s
    ",s[i]);
                    break;
                }
            }
        }
        trie.del(trie.root);    //内存回收
        return 0;
    }
  • 相关阅读:
    常用安卓开发技巧汇总
    安卓开发30:AsyncTask的用法
    JBoss AS7 快速配置
    抓包 把笔记本改造成无线路由器 —— 手机抓包牛刀小试
    Android系统手机端抓包方法
    ApkTool反编译apk,去除广告或者汉化后重新打包apk,并签名
    Android中如何像 360 一样优雅的杀死后台Service而不启动
    android service 的各种用法(IPC、AIDL)
    Android shell 下 busybox,clear,tcpdump、、众多命令的移植
    Servlet3.0中Servlet的使用
  • 原文地址:https://www.cnblogs.com/lidaxin/p/4985999.html
Copyright © 2011-2022 走看看