zoukankan      html  css  js  c++  java
  • HDU 1800 Flying to the Mars(Trie字典树 upper_bound)

    题意:有一个序列 要组成多个子序列

            每个子序列必须单调递增

            问最少组成多少个子序列

    思路1: 因为严格递增 所以每个数只能在一个子序列中出现一次 出现次数最多的数的次数就是答案

               运用 upper_bound(a,a+n,a[i])-lower_bound(a,a+n,a[i]) 求出 

             (由于数据较水 并没有达到30位)      

             upper_bound(begin,end,key),start是查找的起点,end是终点,key是关键值,lower_bound()用法一 样,

             upper_bound()函数,返回第一个大于要找的值得位置(或者理解是这个元素的下一个位置),

             而Lower_bound是小于等于关键字的位 置(或者理解为关键字第一次出现 的位置),

    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #include<stack>
    #define mem(a,b) memset(a,b,sizeof(a))
    #define ll __int64
    #define MAXN 1000
    #define INF 0x7ffffff
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    using namespace std;
    int a[5000];
    int main()
    {
        int i,j,n;
        while(scanf("%d",&n)!=EOF)
        {
            for(i=0; i<n; i++)
                scanf("%d",&a[i]);
            sort(a,a+n);
            int cnt;
            int maxx=0;
            for(i=0; i<n; i++)
            {
                cnt=(upper_bound(a,a+n,a[i])-lower_bound(a,a+n,a[i]));
    
                if(cnt>maxx) maxx=cnt;
            }
            printf("%d
    ",maxx);
        }
        return 0;
    }
    

    思路2:

             当数据达到30位时

             就需要运用字典树记录每个数出现的次数

             

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int  ch[30000+100][20];
    int val[30000+10];
    int sz;   //节点总数
    int idx(char c) {return c-'0';}
    int ans;
    
    void insert(char *s)
    {
        int u=0,n=strlen(s);
        for(int i=0;i<n;i++)
        {
            int c=idx(s[i]);
            if(!ch[u][c])    //节点不存在
            {
                memset(ch[sz],0,sizeof(ch[sz]));
                ch[u][c]=sz++;            //新建节点
            }
            u=ch[u][c];// [上一个数的编号][这个数为c]
        }
        val[u]++;                     //字符串的最后一个字符的附加信息
        if(val[u]>ans) ans=val[u];
    }
    int main()
    {
        int n,i,j,k;
        char s[3000+100];
        while(scanf("%d",&n)!=EOF)
        {
            sz=1;    //初始时只有一个根节点
            memset(ch[0],0,sizeof(ch[0]));
            memset(val,0,sizeof(val));
            ans=1;
            for(i=0;i<n;i++)
            {
                scanf("%s",s);
                j=0;
                while(s[j]=='0') j++;
                insert(s+j);
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    

      

  • 相关阅读:
    Open source physics engine
    Free Platformers: Open Source Gamers Guide to Free Games
    安装路由后,显示已连接,却上不了网?
    http://blog.csdn.net/duanbeibei/article/details/5890436
    javascript权威指南 第8章 笔记2 Kevin
    javascript权威指南 第9章 笔记 Kevin
    javascript权威指南 笔记2 Kevin
    .Net 登录窗口 Kevin
    C# 中读XML时haschrildnodes方法老为true Kevin
    javascript权威指南 第8章 笔记 Kevin
  • 原文地址:https://www.cnblogs.com/sola1994/p/3923653.html
Copyright © 2011-2022 走看看