POJ 1002结题报告

题目网址:http://poj.org/problem?id=1002

题目大意:

企业想拥有令人难忘的电话号码。要一个电话号码让人容易记住,方法之一是号码里面有一个难忘的单词或词组拼写。例如,您可以拨打TUT- GLOP拨打沃特卢大学。有时电话号码只有一部分是单词拼写。当你回到你的酒店,今晚你可以通过拨打310 - GINO吉诺订购比萨饼。另一种方法,设计的电话号码是一个难忘的方式分组数字。你可以通过拨打必胜客" 3个10 "的号码3-10-10-10 来订购比萨.
一个电话号码的标准形式是7个十进制数字用连字符之间的第三和第四位数字(如888-1200 ).一个电话的小键盘提供字母数字的映射,如下所示:
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 。两个电话号码是等价的,如果它们具有相同的标准形式.(他们拨打同一个号码。 )你的公司正在编制当地企业的电话号码目录。作为质量控制过程的一部分,你要检查,没有两个(或以上)的企业目录中的有相同的电话号码.
  输入输入将包括一个案例。输入的第一行中指定的目录中的电话号码的数目(最多10万)作为单独行上的一个正整数.其余各行列出在目录中的电话号码,在单独一行的每个数字。每个电话号码的十进制数字,大写字母(不包括Q和Z )和连字符组成的字符串组成. 整整7个数字或字母的字符串中的字符.
产量
  生成一行输出为每个电话号码,任何形式多次出现。该行应得到的标准形式的电话号码,后跟一个空格,其次是在电话号码出现在目录的次数。电话号码升字典顺序排列输出线。如果没有重复在输入打印线:
No duplicates.
测试数据:
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


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



我的解题思路:

先定义两个二维char数组 str1[][] 和str2[][]  其中str2[][]充当备用数组

①将全部电话号码都翻译成对应的数字,字母Ω转换成相应的数字字符f(Ω)=(Ω-65)/3+2+48   例如A对应于2 f(A)=(‘A’-65)/3+2+48  ==》2
  如果字母Ω是'S' 'V' 'Y'中的任意一个,那么f(Ω)=(Ω-66)/3+2+48

转换后都存入str1[][]中

②消去每一个电话号码中的'-'并存入数组str2[][]中
③利用stdlib.h头文件中的qsort()将str2[][]按字典顺序从大到小排列
④用strcmp(str2[i],str2[i+1])去除重复项

我在解题过程中最初将str1[][]和str2[][]定义在main()函数中结果就直接编译不了了,后来我还是将str1[][]和str2[][]定义在main()函数中,将MAX开小一点就能编译了,提交上去之后一直超时。无奈之下在网上搜了一下,发现只要将大数组定义成函数外面的全局变量,这样就能编译了,我就再次把MAX开大一点,然后在外面定义str1[][]和str2[][]

再次提交之后就AC了,兴奋啊、、

还有一个小细节问题,可以利用memset()函数清空数组,我在调试的时候被str2[][]数组给坑惨了,因为每次上一次的结果都会影响到本次的str2[][]

memset(str2[i],0,sizeof(str2[i]));//清空str2[][]字符数组

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100000

	char str1[MAX][50];
	char str2[MAX][50];

int cmp(const void *a,const void *b)
{
	char *ch1=(char *)a;
	char *ch2=(char *)b;
	return strcmp(ch1,ch2);
}


int main(int argc, char *argv[])
{
	int n;
	//char str1[MAX][50];
	//char str2[MAX][50];
	int i;
	int j;
	int k;
	int sum;
	int rk[MAX];
	int flag;

	while(scanf("%d",&n)!=EOF)
	{
		//getchar();
		for(i=0;i<n;i++)
		{
			memset(str2[i],0,sizeof(str2[i]));//清空str2[][]字符数组
		}
		for(i=0;i<n;i++)
		{
			//gets(str1[i]); gets()函数自己的回车键对他人无影响,但是他人的回车键会对其本身造成影响
			getchar();
			scanf("%s",str1[i]);
			
			for(j=0;str1[i][j]!='\0';j++)//将电话号码中的字母转换成对应的字符数字
			{
				if(str1[i][j]>='A'&&str1[i][j]<='Z')
				{
					if(str1[i][j]=='S'||str1[i][j]=='V'||str1[i][j]=='Y')
					{
						str1[i][j]=(char)((int)(str1[i][j]-66)/3+2+48);
					}
					else
					{
						str1[i][j]=(char)((int)(str1[i][j]-65)/3+2+48);
					}
				}
			}
		}
		
		for(i=0;i<n;i++)//消去每一个电话号码的'-'并存入另一个二维字符数组str2[][]中
		{
			k=0;
			for(j=0;str1[i][j]!='\0';j++)
			{
				if('-'!=str1[i][j])
				{
					str2[i][k]=str1[i][j];
					k++;
					rk[i]=k;
					
				}
			}
			
		}
		
		qsort(str2,n,sizeof(str2[0]),cmp);//将str2[][]中的电话号码按字典顺序从大到小排序
		/*
		测试:
		printf("\n测试:\n");
		for(i=0;i<n;i++)//测试
		{
			puts(str2[i]);
		}
		printf("\n\n");
		*/
		sum=1;
		flag=0;
		for(i=0;i<n-1;i++)//利用strcmp(str2[i],str2[i+1])消除重复项
		{
			
			if(!strcmp(str2[i],str2[i+1]))
			{
				sum++;
				
			}
			else if(sum>1)
			{
				
				for(j=0;j<rk[i];j++)
				{
					if(3==j)
					{
						printf("-");
					}
					printf("%c",str2[i][j]);
				}
				printf(" %d\n",sum);
				sum=1;
				flag=1;
			}






		}
		if(!strcmp(str2[i],str2[i-1]))
		{
			
			if(sum>1)
			{
				for(j=0;j<rk[i];j++)
				{
					if(3==j)
					{
						printf("-");
					}
					printf("%c",str2[i][j]);
				}
				printf(" %d\n",sum);
				flag=1;
			}

		}
		if(!flag)
		{
			printf("No duplicates.\n");
		}

	}



	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值