首页 > 代码库 > Uva 755 487-3125

Uva 755 487-3125

分析:

这道题是刘汝佳灰书上所给的一道题。题目很简单,就是处理字符串并排序输出。但我却卡了很久,试了很多不同的方式,至今使用字符串的一个还没有调试出来。POJ 1002是一道几乎相同的题(不过没有多组数据)。

注意事项:

1. 数据量很大,最好不用cin/cout(当然也可以取消std::同步)。

2. 每个电话号码的初始输入可能很长。

3. 号码长度不够时要补0。

//用整数处理字符串(UVa已过)
#include<iostream>#include<cstdio>#include<cstdlib>#include<limits.h>#include<string>#include<cstring>#include<vector>#include<queue>#include<map>#include<cmath>#include<ctime>#include<algorithm>using namespace std;const int maps[26]={2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,0,7,7,8,8,8,9,9,9,0};int d[100005];int main(){ int i,j,k,T,n,l; bool flag; char b[300]; //cin>>T; scanf("%d",&T); while(T--) { //cin>>n; scanf("%d",&n); for(i=0;i<n;i++) { //cin>>b; scanf("%s",b); l=strlen(b); d[i]=0; for(j=0;j<l;j++) { if(b[j]>=0 && b[j]<=9) d[i]=d[i]*10+b[j]-0; else if(b[j]>=A && b[j]<=Z) d[i]=d[i]*10+maps[b[j]-A]; } } sort(d,d+n); k=1; flag=0; for(i=0;i<n;i++) { if(i==n-1 || d[i]!=d[i+1]) { if(k>1) { printf("%03d-%04d %d\n",d[i]/10000,d[i]%10000,k); flag=1; } k=1; } else k++; } if(flag==false) //cout<<"No duplicates."<<endl; printf("No duplicates.\n"); if(T) //cout<<endl; printf("\n"); } return 0;}

 

//用string处理(UVa已过)
#include<iostream>#include<cstdio>#include<cstdlib>#include<limits.h>#include<string>#include<cstring>#include<vector>#include<queue>#include<map>#include<cmath>#include<ctime>#include<algorithm>using namespace std;const int maps[26]={2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,0,7,7,8,8,8,9,9,9,0};string d[100005];int main(){ int i,j,k,T,n,l; bool flag; char b[300]; //cin>>T; scanf("%d",&T); while(T--) { //cin>>n; scanf("%d",&n); for(i=0;i<n;i++) { //cin>>b; scanf("%s",b); l=strlen(b); d[i]=""; for(j=0;j<l;j++) { if(b[j]>=0 && b[j]<=9) d[i]+=b[j]; else if(b[j]>=A && b[j]<=Z) d[i]+=(char)(maps[b[j]-A]+0); } while(d[i].length()<7) d[i]+="0"; d[i]=d[i].substr(0,3)+"-"+d[i].substr(3,4); } //for(i=0;i<n;i++) cout<<d[i].a<<endl; sort(d,d+n); k=1; flag=0; for(i=0;i<n;i++) { if(i==n-1 || d[i]!=d[i+1]) { if(k>1) { printf("%s %d\n",d[i].c_str(),k); flag=1; } k=1; } else k++; } if(flag==false) //cout<<"No duplicates."<<endl; printf("No duplicates.\n"); if(T) //cout<<endl; printf("\n"); } return 0;}

 

//用字符串处理电话号码,UVa过不了,在POJ上改头换面之后就过了,不知道哪里写错了#include<iostream>#include<cstdio>#include<cstdlib>#include<limits.h>#include<string>#include<cstring>#include<vector>#include<queue>#include<map>#include<cmath>#include<ctime>#include<algorithm>using namespace std;const int maps[26]={2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,0,7,7,8,8,8,9,9,9,0};struct num{    char a[10];};bool operator < (num x, num y){    return strcmp(x.a,y.a)==-1;}num d[100005];int main(){    int i,j,k,T,n,l;    bool flag;    char b[300];    //cin>>T;    scanf("%d",&T);    while(T--)    {        //cin>>n;        scanf("%d",&n);        for(i=0;i<n;i++)        {            //cin>>b;            scanf("%s",b);            l=strlen(b);             for(j=0;j<7;j++) d[i].a[j]=0;                        k=0;            for(j=0;j<l;j++)            {                if(b[j]>=0 && b[j]<=9) d[i].a[k++]=b[j];                else if(b[j]>=A && b[j]<=Z) d[i].a[k++]=maps[b[j]-A]+0;            }            d[i].a[7]=\0;        }        //for(i=0;i<n;i++) cout<<d[i].a<<endl;        sort(d,d+n);        k=1;        flag=0;        for(i=0;i<n;i++)        {            if(i==n-1 || strcmp(d[i].a,d[i+1].a)!=0)            {                if(k>1)                {                    printf("%c%c%c-%c%c%c%c %d\n",d[i].a[0],d[i].a[1],d[i].a[2],d[i].a[3],d[i].a[4],d[i].a[5],d[i].a[6],k);                    flag=1;                }                k=1;            }            else k++;        }        if(flag==false) //cout<<"No duplicates."<<endl;            printf("No duplicates.\n");        if(T) //cout<<endl;            printf("\n");    }    return 0;}

 

//POJ上全用string和map的代码
#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<map>using namespace std;/*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 */char f[26]={2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,0,7,7,8,8,8,9,9,9,0};map<string,int> M;map<string,int>::iterator iter;int main(){ int n,i,j,la; bool flag; char c[300]; string a,b; //cin>>n; scanf("%d",&n); for(i=0;i<n;i++) { //cin>>c; scanf("%s",c); a=c; b.clear(); la=strlen(c); for(j=0;j<la;j++) { if(a[j]==- || a[j]==Q || a[j]==Z) continue; if(b.length()==3) b+=-; if(a[j]>=0 && a[j]<=9) b+=a[j]; else b+=f[a[j]-A]; } M[b]++; } flag=0; for(iter=M.begin();iter!=M.end();iter++) { if(iter->second>1) { flag=1; //cout<<iter->first<<‘ ‘<<iter->second<<endl; printf("%s %d\n",(*iter).first.c_str(),(*iter).second); } } if(!flag) printf("No duplicates.\n"); //cout<<"No duplicates."<<endl; //system("pause"); return 0;}

综合各种题解来看,还是用类似于Trie的方法来做效率最高,不过有些大材小用。据说将电话号码转化为int类型的主要原因是int类型排序更快,但我这里的问题是char类型总是调试不成功,至今也不知为什么。用string和map做的方法很省事,不过很慢,当作对STL的练习也不错。

Uva 755 487-3125