sdut 487-3279【哈希查找,sscanf ,map】

487-3279

Time Limit: 2000ms   Memory limit: 65536K  有疑问?点这里^_^

题目描述

题目链接:

sdut:   http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=1001

poj:    http://poj.org/problem?id=1002

Businesses like to have memorable telephone numbers. One way to make a telephone number memorable is to have it spell a memorable word or phrase. For example, you can call the University of Waterloo by dialing the memorable TUT-GLOP. Sometimes only part of the number is used to spell a word. When you get back to your hotel tonight you can order a pizza from Gino's by dialing 310-GINO. Another way to make a telephone number memorable is to group the digits in a memorable way. You could order your pizza from Pizza Hut by calling their ``three tens'' number 3-10-10-10.

The standard form of a telephone number is seven decimal digits with a hyphen between the third and fourth digits (e.g. 888-1200). The keypad of a phone supplies the mapping of letters to numbers, as follows:

A, B, and C map to 2 
D, E, and F map to 3 
G, H, and I map to 4 
J, K, and L map to 5 
M, N, and O map to 6 
P, R, and S map to 7 
T, U, and V map to 8 
W, X, and Y map to 9

There is no mapping for Q or Z. Hyphens are not dialed, and can be added and removed as necessary. The standard form of TUT-GLOP is 888-4567, the standard form of 310-GINO is 310-4466, and the standard form of 3-10-10-10 is 310-1010.

Two telephone numbers are equivalent if they have the same standard form. (They dial the same number.)

Your company is compiling a directory of telephone numbers from local businesses. As part of the quality control process you want to check that no two (or more) businesses in the directory have the same telephone number.

输入

The input will consist of one case. The first line of the input specifies the number of telephone numbers in the directory (up to 100,000) as a positive integer alone on the line. The remaining lines list the telephone numbers in the directory, with each number alone on a line. Each telephone number consists of a string composed of decimal digits, uppercase letters (excluding Q and Z) and hyphens. Exactly seven of the characters in the string will be digits or letters.

输出

Generate a line of output for each telephone number that appears more than once in any form. The line should give the telephone number in standard form, followed by a space, followed by the number of times the telephone number appears in the directory. Arrange the output lines by telephone number in ascending lexicographical order. If there are no duplicates in the input print the line:

No duplicates.

示例输入

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

示例输出

310-1010 2
487-3279 4
888-4567 3 题目大意:给出大写字母和数字,按照一定的规则映射到电话号码(7位),查找所有的的电话号码,若是有重复,则先按照xxx-xxxx的格式输出电话号码(按照字典序),紧接着一个空格,输出重复的次数;要注意,字母Q和Z不会出现在输入的字符串中,而且,给出的“伪号码”的个数最多可以到100000个。
解题思路:由于伪号码的数量可能会非常大,如果定义二维数组保存伪号码的话,或许会容易导致超内存,最好的法子是使用哈希查找的方法,用一个数组hash[]保存重复的次数,下标保存电话号码,由于电话号码最长是7位,所以要定义一个10000000大的数组,就是hash[10000000],保存的时候就已经自动排完序了,所以省去了排序的步骤,效率相应也会比较高,最后遍历输出满足要求的电话号码和重复次数即可。(注意,若是使用c++的话无法运行程序,好像是超内存了,改成c就能正常运行了,真心不知道什么原因)
代码:
 #include<stdio.h>
#include<string.h>
int hash[]={};
int zhuanzhi(int n)
{
int sum=,i;
for(i=;i<n;i++)
sum*=;
return sum;
}
int zhuanhuan(char f[])
{
int sum=,i;
int t=strlen(f);
for(i=t-;i>=;i--)
{
sum=sum+(f[i]-'')*zhuanzhi(t-i);
}
return sum;
}
int main()
{
int zong,i,j;
scanf("%d",&zong);
while(zong--)
{
char f[],g[];
scanf("%s",f);
int s=-;
for(i=;f[i]!='\0';i++)
{
switch(f[i])
{
case '':
g[++s]='';
break;
case '':
g[++s]='';
break;
case 'A':case 'B':case 'C':case '':
g[++s]='';
break;
case 'D':case 'E':case 'F':case '':
g[++s]='';
break;
case 'G':case 'H':case 'I':case '':
g[++s]='';
break;
case 'J':case 'K':case 'L':case '':
g[++s]='';
break;
case 'M':case 'N':case 'O':case '':
g[++s]='';
break;
case 'P':case 'R':case 'S':case '':
g[++s]='';
break;
case 'T':case 'U':case 'V':case '':
g[++s]='';
break;
case 'W':case 'X':case 'Y':case '':
g[++s]='';
break;
}
}
g[++s]='\0';
hash[zhuanhuan(g)]++;
}
int count=;
for(i=;i<;i++)
if(hash[i]>)
{
printf("%03d-%04d %d\n",i/,i%,hash[i]);
count++;
}
if(count==)printf("No duplicates.\n");
return ;
}

方法二:用c++标准模板库关联容器map做,在sdut上ac了,但是在poj上超时了,不知道问题出在哪里。问题找到了,交的时候要选择“c++”,而默认的提交方式是“g++”,所以要注意这一点才行。

 #include<iostream>
#include<string>
#include<map>
using namespace std;
int main()
{
int n;
cin>>n;
map<string,int>mapx;
pair<map<string,int>::iterator,bool>pairx;
int i;
while(n--)
{
string f,temp("");
cin>>f;
int flag=;
for(i=; i<=f.length(); i++)
{
if(flag==)
{
temp.append("-");
flag++;
}
if(f[i]=='A'||f[i]=='B'||f[i]=='C'||f[i]=='')
{
temp.append("");
flag++;
}
else if(f[i]=='D'||f[i]=='E'||f[i]=='F'||f[i]=='')
{
temp.append("");
flag++;
}
else if(f[i]=='G'||f[i]=='H'||f[i]=='I'||f[i]=='')
{
temp.append("");
flag++;
}
else if(f[i]=='J'||f[i]=='K'||f[i]=='L'||f[i]=='')
{
temp.append("");
flag++;
}
else if(f[i]=='M'||f[i]=='N'||f[i]=='O'||f[i]=='')
{
temp.append("");
flag++;
}
else if(f[i]=='P'||f[i]=='R'||f[i]=='S'||f[i]=='')
{
temp.append("");
flag++;
}
else if(f[i]=='T'||f[i]=='U'||f[i]=='V'||f[i]=='')
{
temp.append("");
flag++;
}
else if(f[i]=='W'||f[i]=='X'||f[i]=='Y'||f[i]=='')
{
temp.append("");
flag++;
}
else if(f[i]=='')
{
temp.append("");
flag++;
}
else if(f[i]=='')
{
temp.append("");
flag++;
}
}
pairx=mapx.insert(pair<string,int>(temp,));
if(pairx.second==)
{
++pairx.first->second;
}
else continue;
}
int flag2=;
map<string,int>::iterator p;
for(p=mapx.begin(); p!=mapx.end(); p++)
{
if(p->second==)
continue;
else
{
cout<<p->first<<" "<<p->second+<<endl;
flag2=;
}
}
if(flag2==)
{
cout<<"No duplicates."<<endl;
}
return ;
}
 
上一篇:最终排名 sdut 2446


下一篇:Ambari组件黄色预警