• Codeforces Round #451 Div. 2 C D E


    C。Phone Numbers

    之前没有做过字典树……感觉这个题字典树也能做……就拿来练一练字典树……板子好多地方写的都不够好,还需要继续改……

    emmm这个……卡了好久啊……不过好在还是debug出来了……orz

    虽然是处理后缀的问题,但是只需要reverse一下就可以变成前缀问题了2333333,然后每一次的字符串都插进去,最后从叶子到根遍历输出就可以了……

    不过我好像……连叶子到根的遍历都写不好呜呜呜……ps:这里只是为了用trie而用trie……其实用map维护一下直接暴力求解就可以……

    //trie树
     /*1. 字符串检索
       2.词频统计
       3.字符串排序  先序遍历
       4.前缀匹配
       */
    #include<bits/stdc++.h>
    using namespace std;
    const int MAX=10;
    string number;
    int now,cnt=0;
    int crt[25];
    struct trie{
        trie *next[MAX];
        int v=0;
    };
    trie *root[20];
    trie* creat_trie()
    {
        trie *temp=(trie*)malloc(sizeof(trie));
        for(int i=0;i<10;i++)
         temp->next[i]=NULL;
        return temp;
    }
    void insert_trie(trie *r,string s,int k)
    {
        trie *p=r;
        for(int i=0;i<s.length();i++)
        {
            int id=s[i]-'0';
            if(p->next[id]==NULL)
                p->next[id]=creat_trie();
            p=p->next[id];
        }
    }
    void search_trie(trie *r,int k)
    { 
        int c=0;
        for(int i=0;i<10;i++)
        {
          if(r->next[i]!=NULL)
          {
           c++;
           search_trie(r->next[i],k); 
          }
        } 
        if(c==0&&r->v!=-1) {
        crt[k]++;
        r->v=-1;
       }
    }
    void print(trie *r)
    {
        if(r->v==-1)
        { 
           reverse(number.begin(),number.end());
           cout<<number<<" ";
           reverse(number.begin(),number.end());
           return ;
        }
          for(int i=0;i<10;i++)
       {
           if(r==root[now])
           number="";
           if(r->next[i]!=NULL)
           {
         number+=char(i+'0');
           print(r->next[i]);
           number=number.substr(0,number.length()-1);
        }
       }
       
    }
    int main()
    {
        int n,m;
        map<string,int>e;
        string a,b;
        cin>>n;
        memset(crt,0,sizeof(crt));
        for(int i=0;i<=n;i++)
          root[i]=creat_trie();
        while(n--)
        {
            cin>>a;
            if(e[a]==0)
             e[a]=++cnt;
            cin>>m;
            now=e[a];
            while(m--)
            {
                cin>>b;
                reverse(b.begin(),b.end());
                insert_trie(root[now],b,now);
            }
        }
        cout<<e.size()<<endl;
        map<string,int>::iterator it;
        for(it=e.begin();it!=e.end();it++)
        {
            cout<<it->first<<" ";
            now=it->second;
            search_trie(root[now],now);
            cout<<crt[now]<<" ";
            print(root[now]);
            cout<<endl;
        }
        return 0;
    }

    (好像还有个后缀树啥的……emmmm还没有学习……码着先)

    D。Alarm Clock

    是个前缀和+贪心的问题么……看大佬简洁的代码是那么处理的,自己搞得太复杂了……还……好多bug

    需要好好想想哪些用前缀和处理更简洁,比如像这种多长时间内的,多大长度内的问题,可以考虑用前缀和?

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll n,m,k,b;
    ll a[1000005];
    int main()
    {
        cin>>n>>m>>k;
        memset(a,0,sizeof(a));
        for(int i=0;i<n;i++)
        {
          cin>>b;
          a[b]=1;     
        }
        int ans=0;
        for(int i=1;i<=m;i++)
        {
            a[i]+=a[i-1];
            if(a[i]>=k)
            {
                ans+=(a[i]-(k-1));
                a[i]=k-1;
            }
        }
        for(int i=m+1;i<1e6+5;i++)
        {
            a[i]+=a[i-1];
            b=a[i]-a[i-m];
            if(b>=k)
            {
                ans+=(b-k+1);
                a[i]=a[i-m]+k-1;
            }
        }
        cout<<ans<<endl;
        return 0;
    }

    E。Squares and not squares

    想着暴力dfs我也是傻了……orz

    依旧还是贪心,这次题……好多贪心……

    2种情况……为平方数的个数m<=n/2,ans=(n/2-m)个非平方数变成平方数和的最小值

                                                 m>=n/2,ans=(m-n/2)个平方数变为非平方数和的最小值(非0值每个数只需要+1,0需要+2)//注意0需要特判,良心样例有没有啊!

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll n,a[200005],ans;
    ll b[200005];
    int main()
    {
        cin>>n;
        int cnt=0,cnt0=0,cnt1=0;
        for(int i=0;i<n;i++)
        {
         cin>>a[i]; 
         ll c=sqrt(a[i]);
         ll minn=min(a[i]-pow(c,2),pow(c+1,2)-a[i]);
         b[i]=minn;
         if(b[i]==0)
          cnt++;
        if(a[i]==0) cnt0++;
        }
        if(cnt>=n/2&&cnt0<=n/2) ans=cnt-n/2;
        else if(cnt0>n/2)
            ans=cnt-cnt0+2*(cnt0-n/2);
        else 
        {
            ans=0;
               sort(b,b+n);
            for(int i=0;i<n/2;i++)
               ans+=b[i]; 
        }
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    Mybatis学习(3)实现数据的增删改查
    Mybatis学习(2)以接口的方式编程
    Mybatis学习(1)开发环境搭建
    Apache Commons 工具类介绍及简单使用
    JAVA枚举使用详解
    Spring中的<context:annotation-config/>配置
    SpringMVC(12)完结篇 基于Hibernate+Spring+Spring MVC+Bootstrap的管理系统实现
    SpringMVC(11)表单标签
    面试题
    开发辅助网址
  • 原文地址:https://www.cnblogs.com/Egoist-/p/8094416.html
Copyright © 2020-2023  润新知