Eligibility (很有STL含金量的解法)

Eligibility


其实题意很简单,时限也不紧,直接做,也许可以过。鄙人最近在做STL,看什么题,只要是有关字符串的,都想用STL做(当然,数据量大的还是怕会超时)。


有T组数据每组数据n行,每行2个要点,队名 年份,表示<队名>在<年份>参加过该比赛。参加比赛次数超过5次(包含)的,视为不合格。要求输出合格的队名。每组数据都是独立的,没有相互的联系性。【队名中可能会有空格】


开始没有看到队名中间有空格这个,导致输入出错,一直都与AC无缘。


除了队名这里有点郁闷外,很多人WA的原因,是(特地改写代码后测试过)同一条信息可能会重复出现。也就是说同一组测试数据中可能会出现多行相同的信息(同一组在同一年参加比赛的一条信息出现多次)。


还有,输出的时候,要求按字典序输出。在map和set里面是无法排序的,只能是用这些容器把数据筛选出来之后,排序后再输出。


对此,我只想说,我们用STL吧!


该题第一次A是用的一个队友的思想(见代码二),因为开始我一直TLE,以为自己的思路出了问题,他的代码是WA,所以用了他的代码改的输入。A了之后,发现自己的思想(见代码一),也是对的,只是输入是没有处理空格问题。这两个代码都用到STL,用到容器,string之类的,但是,我的代码容器用的更好(毕竟我是做STL的,他是做动归的,对容器不是很熟)。



SolutionUserProblemLanguageJudge ResultMemoryTime UsedCode LengthSubmit Time
903752011404500711410GNU C++Accepted1232KB78ms1005B2013-10-08 10:04:15.0
897892011404500711410GNU C++Accepted1292KB156ms1896B2013-10-07 15:01:51.0


不同的思维,效率也有所不同,比起一般的思维来说,STL的更省篇幅,省时间,没想到还省内存了!呵呵大笑


这里仅分析自己的思维的代码!


【代码一】

1、数据结构:

(1)map<string ,set<string> >ms;     //嵌套容器。

        表示<队名>string参加了set里面所有年份的比赛(比赛的场数就是set.size())。

         不必担心信息重复问题,因为set不允许插入相同的关键字(直接屏蔽曾经出现过的年份)。

        后面为了测试证明测试数据中同一条信息会重复出现,特地改成了map<string ,multiset<string> >ms;结果WA了(2)priority_queue<string ,vector<string>,greater<string> > pq;   //值小优先的优先队列

        符合输出条件的队伍的队名筛选出来后,存入优先队列形成字典序后,直接输出即可


2、处理步骤:

(1)输入信息,并处理(主要是处理队名中的空格问题,直接截取即可)

(2)将信息压入容器:ms[<队名>].insert(<年份>)

(3)筛选信息,定义迭代器map<string,set<string> >::iterator it;一次访问容器中队伍的信息,遇到it->second.size()<5的就将其关键字it->first压入到优先队列中备用

(4)将优先队列中所有的信息全部输出即可(不用担心字典序哦,优先队列早就排好了)


#include<stdio.h>
#include<set>
#include<map>
#include<string>
#include<queue>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
    int t,n;
    int i=0;
    char a[40];
    map<string,set<string> > ms;
    scanf("%d",&t);
    while(t--)
    {
        ms.clear();
        scanf("%d",&n);
        getchar();
        while(n--)
        {
            gets(a);
            string s=a;
            int str=s.size();
            while(s[str-1]==' '&&str--);
            ms[s.substr(0,str-5)].insert(s.substr(str-4,4));
        }
        i++;
        printf("Case #%d:\n",i);
        priority_queue<string ,vector<string>,greater<string> > pq;
        map<string,set<string> >::iterator it;
        for(it=ms.begin();it!=ms.end();it++)
            if(it->second.size()<5) pq.push(it->first);
        while(!pq.empty()) printf("%s\n",pq.top().c_str()),pq.pop();
    }
    return 0;
}

【代码二】

#include<string.h>
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<string>
#include<algorithm>
#include<map>
using namespace std;

string ss[510];
int cnt,r=1;

struct node
{
    string a;
    string b;
}list[510];

bool cmp(node x,node y)
{
    if(x.a==y.a)return x.b<y.b;
    return x.a<y.a;
}

int main()
{
    int T;
    int i,j,n,year,ans;
    string str;
    map<string,int>cp;

    scanf("%d",&T);

    while(T--)
    {
        scanf("%d",&n);
        getchar();

        for(i=1;i<=n;i++)
        {
            char x[100];
            gets(x);
            list[i].a=x;
            int str1=list[i].a.size();
            while(x[str1-1]==' '&&str1--);
            list[i].b=list[i].a.substr(str1-4,4);
            list[i].a=list[i].a.substr(0,str1-5);
        }

        sort(list+1,list+n+1,cmp);

        ans=0;
        cp.clear();

        for(i=1;i<n;i++)
        {
            if(list[i].a==list[i+1].a &&list[i].b == list[i+1].b)
            else cp[list[i].a]++;
        }

        cp[list[i].a]++;
        map<string,int>::iterator it;
        cnt = 0;

        for(it = cp.begin();it!=cp.end();it++)
        {
            if(it->second>=1 && it->second<5)
                ss[cnt++] = it->first;
        }

        sort(ss,ss+cnt);

        printf("Case #%d:\n",r++);

        for(i=0;i<cnt;i++) cout<<ss[i]<<endl;
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值