P2037 电话号码

题目描述

一串由长长的数字组成的电话号码通常很难记忆。为了方便记忆,有种方法是用单词来方便记忆。例如用“Three Tens”来记忆电话3-10-10-10。

电话号码的标准形式是七位数字,中间用连字号分成前三个和后四个数字(例如:888-1200)。电话号码可以用字母来表示。以下是字母与数字的对应:

A,B和C对应2

D,E和F对应3

G,H和I对应4

J,K和L对应5

M,N和O对应6

P,R和S对应7

T,U和V对应8

W,X和Y对应9

你会发现其中没有字母Q和Z。电话中的连字号是可以忽略。例如TUT-GLOP的标准形式是888-4567,310-GINO的标准形式是310-4466,3-10-10-10的标准形式是310-1010。

如果两个电话号码的标准形式是一样的,那么这两个电话号码就是一样的。

现在有一本电话簿,请从中找出哪些电话号码是重复的。

输入输出格式

输入格式:

 

第一行一个正整数N,表示有多少个电话号码。

以下N行,每行一个电话号码,电话号码由数字、大写字母(除Q、Z)和连字符组成。电话号码长度不会超过1000。所有电话号码都合法。

 

输出格式:

 

将所有重复的电话号码按字典序以标准形式输出,并且在每个电话号码后跟一个整数,表示该电话号码共出现了多少次,电话号码和整数间用一个空格隔开。不要输出多余空行。

如果没有重复的电话号码,则输出:No duplicates.

 

输入输出样例

输入样例#1: 复制
3
TUT-GLOP
3-10-10-10
310-1010
输出样例#1: 复制
310-1010 2

说明

【数据范围】

对于30%的数据,N<=20。

对于50%的数据,N<=10000。

对于100%的数据,N<=100000。

 

不用开map

/*用一个map把所有的字母表示的数字存起来,0和1题目中没说,但也要表示。
一个<string,int>类型的map表示a这个字符串出现的次数。
把每个读入的字符串转化为标准形式存起来,如果有出现次数超过两次的,存起来,答案数++。
最后将答案按字典序排序输出。  (如果map的初始化写到了函数里,别忘记调用!!!,一开始没调用,全输出的空格,调了半个多小时)。*/ 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<map>
#include<string>
using namespace std;

int n,cnt,now,pos,sum[100005];
string s,temp,tot[100005];
map<char,char> excel;
map<string,int> a;
struct Ans
{
    int cs;
    string chuan;
}ans[100005];

void init()        //初始化函数 
{
    excel['0']='0';excel['1']='1';
    excel['A']=excel['B']=excel['C']=excel['2']='2';
    excel['D']=excel['E']=excel['F']=excel['3']='3';
    excel['G']=excel['H']=excel['I']=excel['4']='4';
    excel['J']=excel['K']=excel['L']=excel['5']='5';
    excel['M']=excel['N']=excel['O']=excel['6']='6';
    excel['P']=excel['R']=excel['S']=excel['7']='7';
    excel['T']=excel['U']=excel['V']=excel['8']='8';
    excel['W']=excel['X']=excel['Y']=excel['9']='9';
}

bool cmp(Ans a,Ans b)
{
    return a.chuan+b.chuan<b.chuan+a.chuan;
}

int main()
{
    init();        //千万千万别忘记调用 
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        cin>>s;
        temp.clear();pos=0;        //将temp清空,pos归零 
        for(int j=0;j<s.length();j++)
        {
            if(s[j]!='-')    //转化为数字 
            {
                temp+=excel[s[j]];
                pos++;
            }
            if(pos==3) temp+='-',pos=-999999999;    //到了该加'-'的地方,加上'-',同时将pos设为负值,防止重复添加 
        }
        if(!a[temp]) tot[++cnt]=temp;    //如果这个字符串没出现过,将这个字符串加入到已有的字符串中 
        a[temp]++;    //该字符串出现的次数++ 
    }
    for(int i=1;i<=cnt;i++)        //找哪个字符串是重复的 
    {
        if(a[tot[i]]>1)
        {
            ans[++now].chuan=tot[i];    //存答案 
            ans[now].cs=a[tot[i]];
        }
    }
    if(!now)    //没有重复的 
    {
        printf("No duplicates.");
        return 0;
    }
    sort(ans+1,ans+now+1,cmp);        //按字典序排列 
    for(int i=1;i<=now;i++)
    {
        cout<<ans[i].chuan<<' ';
        printf("%d\n",ans[i].cs);
    }
    return 0;
}
map TLE一个点
/*用一个map把所有的字母表示的数字存起来,0和1题目中没说,但也要表示。
一个<string,int>类型的map表示a这个字符串出现的次数。
把每个读入的字符串转化为标准形式存起来,如果有出现次数超过两次的,存起来,答案数++。
最后将答案按字典序排序输出。  (如果map的初始化写到了函数里,别忘记调用!!!,一开始调用,全输出的空格,调了半个多小时)。*/ 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<map>
#include<string>
using namespace std;

int n,cnt,now,pos,sum[100005];
string s,temp,tot[100005];
char excel[100];
map<string,int> a;
struct Ans
{
    int cs;
    string chuan;
}ans[100005];

void init()        //初始化函数 
{
    excel['0']='0';excel['1']='1';
    excel['A']=excel['B']=excel['C']=excel['2']='2';
    excel['D']=excel['E']=excel['F']=excel['3']='3';
    excel['G']=excel['H']=excel['I']=excel['4']='4';
    excel['J']=excel['K']=excel['L']=excel['5']='5';
    excel['M']=excel['N']=excel['O']=excel['6']='6';
    excel['P']=excel['R']=excel['S']=excel['7']='7';
    excel['T']=excel['U']=excel['V']=excel['8']='8';
    excel['W']=excel['X']=excel['Y']=excel['9']='9';
}

bool cmp(Ans a,Ans b)
{
    return a.chuan+b.chuan<b.chuan+a.chuan;
}

int main()
{
    init();        //千万千万别忘记调用 
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        cin>>s;
        temp.clear();pos=0;        //将temp清空,pos归零 
        for(int j=0;j<s.length();j++)
        {
            if(s[j]!='-')    //转化为数字 
            {
                temp+=excel[s[j]];
                pos++;
            }
            if(pos==3) temp+='-',pos=-999999999;    //到了该加'-'的地方,加上'-',同时将pos设为负值,防止重复添加 
        }
        if(!a[temp]) tot[++cnt]=temp;    //如果这个字符串没出现过,将这个字符串加入到已有的字符串中 
        a[temp]++;    //该字符串出现的次数++ 
    }
    for(int i=1;i<=cnt;i++)        //找哪个字符串是重复的 
    {
        if(a[tot[i]]>1)
        {
            ans[++now].chuan=tot[i];    //存答案 
            ans[now].cs=a[tot[i]];
        }
    }
    if(!now)    //没有重复的 
    {
        printf("No duplicates.");
        return 0;
    }
    sort(ans+1,ans+now+1,cmp);        //按字典序排列 
    for(int i=1;i<=now;i++)
    {
        cout<<ans[i].chuan<<' ';
        printf("%d\n",ans[i].cs);
    }
    return 0;
}
char数组AC

 

posted @ 2018-04-04 15:44  whymhe  阅读(406)  评论(0)    收藏  举报