题目来源:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1159
题目大致描述:找出一些给定的用不同方式描述的电话号码中有重复的,并以标准形式输出。
一开始我看到有10S时间,我就用普通的方法做,发现总是超时。后来我学了下C++的map容器,很容易就水过了,
感觉C++里的许多容器和库函数都非常有用。
#include <stdio.h>
#include <iostream>
#include <string>
#include <map>
using namespace std;
int main()
{
int t,n,i,j,tmpt,flag=0;
string table="2223334445556667777888999";
scanf("%d",&t);tmpt=t;
getchar();
while(t--)
{
getchar();
scanf("%d",&n);flag++;
map<string,int>num;
for(i=0;i<n;i++)
{
string str,tmp;
cin>>tmp;
for(j=0;j<tmp.length();j++)
if(tmp[j]=='-')
continue;
else
if(tmp[j]>='0'&&tmp[j]<='9')
str+=tmp[j];
else
str+=table[tmp[j]-'A'];
str.insert(3,"-");
num[str]++;
}
int total=0;
map<string,int>::iterator p;
p=num.begin();
for(;p!=num.end();p++)
if(p->second>1)
{
total++;
cout<<p->first<<" "<<p->second<<endl;
}
if(total==0)
cout<<"No duplicates."<<endl;
if(flag!=tmpt)
cout<<endl;
}
return 0;
}
A了后,我又到网上查了查,发现有用hash做的,自己也写了个,但是在zoj上超内存(浙大的oj,我感觉是很严格的),但在北大的oj上类似的题目(1002)过了,
而且相比而言非常快。
所以觉得用hash做这类题目有很大局限性,特别是电话号码位数较多的情况,碰上这类题目建议用map容器。
#include <stdio.h>
#include <string.h>
int hash[10][10][10][10][10][10][10];
int main()
{
int t,n,i,j,h,a[7],k,l,m,w,tmpt,flag=0,total;
char str[2000];
char table[]="2223334445556667777888999";
scanf("%d",&n);flag++;
memset(hash,0,sizeof(hash));
for(i=0;i<n;i++)
{
scanf("%s",str);
h=0;
for(j=0;str[j];j++)
if(str[j]=='-')
continue;
else
if(str[j]>='0'&&str[j]<='9')
a[h++]=str[j]-'0';
else
a[h++]=table[str[j]-'A']-'0';
hash[a[0]][a[1]][a[2]][a[3]][a[4]][a[5]][a[6]]++;
}
total=0;
for(i=0;i<=9;i++)
for(j=0;j<=9;j++)
for(k=0;k<=9;k++)
for(h=0;h<=9;h++)
for(l=0;l<=9;l++)
for(m=0;m<=9;m++)
for(w=0;w<=9;w++)
if(hash[i][j][k][h][l][m][w]>1)
{
total++;
printf("%d%d%d-%d%d%d%d %d\n",i,j,k,h,l,m,w,hash[i][j][k][h][l][m][w]);
}
if(total==0)
printf("No duplicates.\n");
return 0;
}