POJ 1002

1002其实算法蛮简单的。。但是为何通过率很低呢。。。应该是测试数据好变态。。。

题目大意:不用我翻译了,直接有中文的。。

企业喜欢用容易被记住的电话号码。让电话号码容易被记住的一个办法是将它写成一个容易记住的单词或者短语。例如,你需要给滑铁卢大学打电话时,可以拨打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.

------------------------------------------------------------我是华丽的分割线----------------------------------------------------------

我没有注意到题目里面的“连字符不需要拨号,可以任意添加和删除”,所以变态一点说,‘-’字符可以是无数多个。。。

于是我搞了3次WA。。。

算法就是替换字符串里面的字母和下划线然后再排个序最后按照标准格式打印。虽然说排序要求的是字典序,但是,由于号码的位数固定为7位,所以字典序和真实数据的按照大小排序就是一样的了。

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct __data{
   int telNum;
   int repTim;
} da;

int main(){
	
	da *data;
	int numOfRecord,i;
	char temp[2000];  //数组开小了会WA。。。我了个擦。。。多么变态的测试数据啊。。第二第三次WA都是这个问题
	
	scanf("%d",&numOfRecord);
	
	data=(da *)calloc(numOfRecord,sizeof(da));
	
	for (i=0;i<numOfRecord;i++){
		scanf("%s",temp);
		stdlizeNum(temp,&(data[i]));
	}
	sortPrintf(data,numOfRecord);

  free(data);
  return 0;
}

int stdlizeNum(char *num,da *ans){
  int len=strlen(num);
  int i;
  int k=0;
  
  ans->repTim=0;
  ans->telNum=0;
  for (i=0;i<len;i++){
     switch(num[i]){
     case 'A':
     case 'B':
     case 'C':
     	 ans->telNum+=2;
     	 ans->telNum*=10;
     break;
     case 'D':
     case 'E':
     case 'F':
     	 ans->telNum+=3;
     	 ans->telNum*=10;
     break;
     case 'G':
     case 'H':
     case 'I':
     	 ans->telNum+=4;
     	 ans->telNum*=10;
     break;
     case 'J':
     case 'K':
     case 'L':
     	 ans->telNum+=5;
     	 ans->telNum*=10;
     break;
     case 'M':
     case 'N':
     case 'O':
     	 ans->telNum+=6;
     	 ans->telNum*=10;
     break;
     case 'P':
     case 'R':
     case 'S':
     	 ans->telNum+=7;
     	 ans->telNum*=10;
     break;
     case 'T':
     case 'U':
     case 'V':
     	 ans->telNum+=8;
     	 ans->telNum*=10;
     break;
     case 'W':
     case 'X':
     case 'Y':
     	 ans->telNum+=9;
     	 ans->telNum*=10;
     break;
     case '-':
     break;
     default:
     	 ans->telNum+=(int)(num[i]-'0');
     	 ans->telNum*=10;
     break;
     }
  }
  ans->telNum/=10;
}
int sortCmp_fun(const void *a,const void *b){
   
   return ((*(da *)a).telNum)-((*(da *)b).telNum);

}
int sortPrintf(da *input,int len){
	int i,offOn;
	
	qsort(input,len,sizeof(da),sortCmp_fun);
  
  for (i=0;i<len;i++){
     if (input[i].telNum==input[i-1].telNum){
        input[i].repTim=input[i-1].repTim+1;
        input[i-1].repTim=0;
     }
  }

  offOn=0;
  for (i=0;i<len;i++){
     if (input[i].repTim!=0){
     	  offOn=1;
        printf("%03d-%04d %d\n",input[i].telNum/10000,input[i].telNum%10000,input[i].repTim+1);  //"%d"这里不会出'0',而"%0d"会打印出来,第一次WA就是这里出错了
     }
  }
  if (offOn==0){
  	printf("No duplicates.\n");
  }

}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值