POJ 1002

487-3279
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 218209   Accepted: 38038

Description

企业喜欢用容易被记住的电话号码。让电话号码容易被记住的一个办法是将它写成一个容易记住的单词或者短语。例如,你需要给滑铁卢大学打电话时,可以拨打TUT-GLOP。有时,只将电话号码中部分数字拼写成单词。当你晚上回到酒店,可以通过拨打310-GINO来向Gino's订一份pizza。让电话号码容易被记住的另一个办法是以一种好记的方式对号码的数字进行分组。通过拨打必胜客的“三个十”号码3-10-10-10,你可以从他们那里订pizza。 

电话号码的标准格式是七位十进制数,并在第三、第四位数字之间有一个连接符。电话拨号盘提供了从字母到数字的映射,映射关系如下: 
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。 

如果两个号码有相同的标准格式,那么他们就是等同的(相同的拨号) 

你的公司正在为本地的公司编写一个电话号码薄。作为质量控制的一部分,你想要检查是否有两个和多个公司拥有相同的电话号码。 

Input

输入的格式是,第一行是一个正整数,指定电话号码薄中号码的数量(最多100000)。余下的每行是一个电话号码。每个电话号码由数字,大写字母(除了Q和Z)以及连接符组成。每个电话号码中只会刚好有7个数字或者字母。

Output

对于每个出现重复的号码产生一行输出,输出是号码的标准格式紧跟一个空格然后是它的重复次数。如果存在多个重复的号码,则按照号码的字典升序输出。如果输入数据中没有重复的号码,输出一行: 
No duplicates. 

Sample Input

12
4873279
ITS-EASY
888-4567
3-10-10-10
888-GLOP
TUT-GLOP
967-11-11
310-GINO
F101010
888-1200
-4-8-7-3-2-7-9-
487-3279

Sample Output

310-1010 2
487-3279 4
888-4567 3

Source

East Central North America 1999

Translator

北京大学程序设计实习2007
  首先这道题要是用Map会TLE,目前我只知道Hash能过。
先贴出Map的代码,改了好久还是一直T大哭
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <map>
#include <string>
#include <stack>
#include <ctype.h>
#include <vector>
#include <queue>
#include <set>

using namespace std;
#define MAXN 100010
#define Inf 0x7ffffff
#define eps 1e10-8
#define mod 1000000007
typedef long long LL;
const double PI = acos(-1.0);
typedef double D;
//#define Online_Judge
#define outstars cout << "***********************" << endl;
char s1[320];

bool cmp(const pair<string,int>& a,const pair<string,int>& b){
	for (int i=0;i<8;i++){
		if (a.first[i]==b.first[i]) continue;
		else return a.first[i]<b.first[i];
	}
	return true;
}

int main()
{
#ifdef Online_Judge
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
#endif // Online_Judge
    map <string , int> m;
    map <string , int> ::iterator itr;
    int T;
    scanf("%d",&T);
    char tran[100];
	tran['1']='1';
	tran['0']='0';
	tran['A']=tran['B']=tran['C']=tran['2']='2';
	tran['D']=tran['E']=tran['F']=tran['3']='3';
	tran['G']=tran['H']=tran['I']=tran['4']='4';
	tran['J']=tran['K']=tran['L']=tran['5']='5';
	tran['M']=tran['N']=tran['O']=tran['6']='6';
	tran['P']=tran['R']=tran['S']=tran['7']='7';
	tran['T']=tran['U']=tran['V']=tran['8']='8';
	tran['W']=tran['X']=tran['Y']=tran['9']='9';
    while(T--)
    {
        scanf("%s",s1);
        int count = 0;
        string s2;
        for(int i = 0  ; count < 7 ; i++)
        {
            if(s1[i] == '-')continue;
            s2 += tran[s1[i]];
            count ++;
            if(count == 3)s2 += '-';
        }
        if((itr = m.find(s2)) == m.end())
        {
            m.insert(make_pair(s2 , 1));
        }
        else (*itr).second++;

    }

//    int num = 0 ;
//    for(map<string, int>::iterator iter = m.begin(); iter != m.end(); ++iter)
//    {
//        if(m[iter -> first] == 1 )
//        {
//            num++;
//            continue;
//        }
//        printf("%s %d\n",iter -> first.c_str() , iter -> second);
//    }
//    if(num == m.size())printf("No duplicates.\n");
    	vector<	pair<string,int> > vec;
	for (itr=m.begin();itr!=m.end();itr++){
		if (itr->second>1)
		vec.insert(vec.end(),*itr);
	}
	sort(vec.begin(),vec.end(),cmp);
	int total=vec.size();
	for (int i=0;i<total;i++){
		cout<<vec[i].first<<' '<<vec[i].second<<endl;
	}
	if (vec.size()==0) cout<<"No duplicates."<<endl;
    return 0;
}
然后是AC的Hash代码(参照Discuss里的一位神牛的代码)
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <map>
#include <string>
#include <stack>
#include <ctype.h>
#include <vector>
#include <queue>
#include <set>

using namespace std;
#define MAXN 100010
#define Inf 0x7ffffff
#define eps 1e10-8
#define mod 1000000007
typedef long long LL;
const double PI = acos(-1.0);
typedef double D;
//#define Online_Judge
#define outstars cout << "***********************" << endl;
char s[320];
int a[MAXN];
int Hash()
{
    int sum = 0;
    int count = 0;
    for(int i = 0  ; count < 7 ; i++)
    {
        if(s[i] >= '0'&&s[i] <= '9')
        {
            count++;
            sum *= 10;
            sum += s[i] - '0';
        }
        else if(s[i] >= 'A'&&s[i] <= 'Z')
        {
            sum *= 10;
            count++;
            sum += ((s[i] - 'A' - (s[i] > 'Q')) / 3 + 2);///膜拜了,相当于从第三个开始每三个一组为一个hash值,Q,Z不算。。。
        }
    }
    return sum;
}
int main()
{
#ifdef Online_Judge
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
#endif // Online_Judge
    int T;
    scanf("%d\n",&T);
    for(int i =0  ;i < T ; i++)
    {
        gets(s);
        a[i] = Hash();
    }
    sort(a , a + T);
    bool flag = false;
    T--;
    for(int i = 0 , num = 1 ; i < T ; i += num = 1)
    {
        while(a[i] == a[i + 1])
        {
            num++;
            i++;
        }
        if(num > 1)
        {
            printf("%03d-%04d %d\n",a[i] / 10000 , a[i] % 10000 , num);///一个数分为两部分输出
            flag = true;
        }
    }
    if(!flag)printf("No duplicates.\n");
    return 0;
}




你可能感兴趣的:(hash,ACM)