zoukankan      html  css  js  c++  java
  • BestCoder Round #92 1001 Skip the Class —— 字典树 or map容器

    题目链接:http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?cid=748&pid=1001


    题解:

    1.trie树

    关键是如何将科目与分数进行对应,即如果将字符串与数字对应。由于之前解除了字典树,所以就想到用字典树存储单词,并为每种编上编号,之后就用这个编号与分数对应。

    就个人观点而言,a[][]数组应该不用清零,因为下个case会将之前的case覆盖掉,但是错了,也找不出原因。所以以后为了安全起见,不管是否会被覆盖,都清零吧,这样保险一点。

    代码如下:

     1 #include<bits/stdc++.h>//字典树  
     2   
     3 using namespace std;  
     4   
     5 int a[105][105],deg[105], b[105],vis[105],sum;  
     6 //a[][]记录单词的值,从1开始记录。deg[]记录单词有多少个值。sum为单词的种数。  
     7   
     8 typedef struct node//字典树的结点  
     9 {  
    10     struct node *next[26];  
    11     int pos;  
    12 }Trie, *PT;  
    13   
    14 int init(PT &p)//初始化结点  
    15 {  
    16     p = (PT)malloc(sizeof(Trie));  
    17     p->pos = 0;  
    18     for(int i = 0; i<26; i++)  
    19         p->next[i] = NULL;  
    20 }  
    21   
    22 //访问字典树,若果单词已存在,则返回这个单词的编号,如果不存在,则编号加1,并返回。  
    23 int trie(char *s, int k, PT &p)  
    24 {  
    25     if(!s[k])  
    26     {  
    27         if(p->pos) return p->pos;  
    28         p->pos = ++sum;  
    29         return p->pos;  
    30     }  
    31   
    32     else  
    33     {  
    34         if(!p->next[s[k]-'a'])  
    35             init(p->next[s[k]-'a']);  
    36         return trie(s,k+1,p->next[s[k]-'a']);  
    37     }  
    38 }  
    39   
    40 int cmp(int a,int b)  
    41 {  
    42      return a > b;  
    43 }  
    44   
    45 int main()  
    46 {  
    47     int T,n,val,ans;  
    48     char s[15];  
    49     PT p;  
    50     scanf("%d",&T);  
    51     while(T--)  
    52     {  
    53         init(p);  
    54         scanf("%d",&n);  
    55         ans = 0; sum = 0;  
    56         memset(deg,0,sizeof(deg));  
    57         memset(vis,0,sizeof(vis));  
    58         memset(a,0,sizeof(a));//为什么少了这步会出错,这步好像不是必要的吧?  
    59         for(int i = 0; i<n; i++)  
    60         {  
    61             scanf("%s%d",s,&val);  
    62             b[i] = trie(s,0,p);//获取单词的编号,并将其储存到b[]中,  
    63             a[b[i]][deg[b[i]]++] = val;//更新a数组和deg数组  
    64         }  
    65   
    66         for(int i = 0; i<n; i++)  
    67         {  
    68           if(!vis[b[i]])//如果没有访问编号为b[i]的单词,则访问。  
    69           {   //对这个单词的值进行排序,选其前二,并标为已访问。  
    70               sort(a[b[i]],a[b[i]]+deg[b[i]],cmp);  
    71               vis[b[i]] = 1;  
    72               ans += a[b[i]][0] + a[b[i]][1];  
    73           }  
    74         }  
    75         printf("%d
    ",ans);  
    76     }  
    77     return 0;  
    78 }  
    View Code


    2.map容器

    其实做题时想到用c++的map会很方便,只可惜没有学map的操作。也好,现在补回来了。

    对于map的认识:

    1.map一个key只能对应一个val,而multimap一个key能对应多个val。所以如果对map的key进行多次复制,其旧val会被新val覆盖。而multimap则插入新的val。

    2.由于map一对一,所以可以直接用map[key] = val,以数组的形式直接赋值,而multimap则只能用map.insert(pair<string,int>("ss",11))进行插入赋值。

    3.要访问元素要使用迭代器map<string,int>::iterator it,last; 4

    4.两种map都自动根据key值进行递增排序。

    代码如下:

     1 #include<bits/stdc++.h>  
     2 #define MAX(a,b) (a>b?a:b)  
     3   
     4 using namespace std;  
     5   
     6 int main()  
     7 {  
     8     int n,val,T;  
     9     char s[15];  
    10     map<string,int> m1,m2;  
    11     map<string,int>::iterator it,last;  
    12     scanf("%d",&T);  
    13     while(T--)  
    14     {  
    15         scanf("%d",&n);  
    16         m1.clear(); m2.clear();//清空map  
    17         for(int i = 0; i<n; i++)  
    18         {  
    19             scanf("%s%d",s,&val);  
    20             //更新第一二大值  
    21             m2[s] = MAX(m2[s],val);  
    22             if(m1[s]<m2[s]) swap(m1[s],m2[s]);  
    23         }  
    24   
    25         int ans = 0;  
    26         for(it = m1.begin(),last = m1.end(); it!=last; it++)  
    27             ans += it->second;  
    28         for(it = m2.begin(),last = m2.end(); it!=last; it++)  
    29             ans += it->second;  
    30         printf("%d
    ",ans);  
    31     }  
    32     return 0;  
    33 }  
    View Code
  • 相关阅读:
    [COCI20142015#1] Kamp
    [CEOI2007]树的匹配Treasury
    [JLOI2016/SHOI2016]侦察守卫
    [POI2015]MOD
    [BJOI2017]机动训练
    [九省联考2018]一双木棋chess
    [清华集训2012]串珠子
    [POI2014]ZALFreight
    [SHOI2009]舞会
    [COCI2019]Mobitel
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/7538767.html
Copyright © 2011-2022 走看看