POJ1002

【题目】

企业想拥有令人难忘的电话号码。要一个电话号码让人容易记住,方法之一是号码里面有一个难忘的单词或词组拼写。例如,您可以拨打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.

【样例输入】
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

解题思路:

由于这道题的复杂度要求比较高,如果直接用字符串来存放输入的话,就会TLE。

所以最好的办法是用int数组来存放。2^32=4'294'967'296,长度已经超过了7,所以没有问题。

然后我考虑用getline(cin,s)来输入字符串,但是发现会runtime error。所以最后只能采用getchar().

接下来是把字符串转换成对应的数字:

遇到‘-’就跳过。

如果遇到大写字母,应该用所给的定义转换。不难发现Q没了,那么在A-P之间有个规律:(ch-'A')/3+2。

由于Q没了,所以R-Y就相当于往前移了一位,所以规律变为(ch-'A'-1)/3+2。

在字符串全部转为数字串之后,题目要求按字典升序排列,所以可以考虑sort函数排序(或qsort)

#include<iostream>
#include<algorithm>
#include<string>
#include<stdlib.h>
using namespace std;

int main(){
	//freopen("in1.txt","r",stdin); 
	int n;
	cin>>n;
	int *a = (int *)malloc(sizeof(int) * (n)+10); 
	//int total=0;
	getchar();//吃掉换行符 
	for(int i=0;i<n;i++){
		int temp=0;
		char ch=getchar();
		while(ch!='\n'){
			if(ch!='-'){
				//temp=temp*10;
				if(ch>='A' && ch<='P'){				
					temp=temp*10+(ch-'A')/3+2;
				}
				else if(ch>='R' && ch<='Y'){
					temp=temp*10+(ch-'A'-1)/3+2;
				}
				else if(ch>='0' && ch<='9'){
					temp=temp*10+ch-'0';
				}
			}
			ch=getchar();			
		}
		a[i]=temp;
	}	
	sort(a,a+n);
	int flag=0;
	for(int i=0;i<n-1;i++){
		int count=1;
		while(i+1<n && a[i]==a[i+1]){
			count++;
			i++;
		}
		if(count>1){
			flag=1;
			printf("%03d-%04d %d\n",a[i] / 10000 ,a[i] % 10000 ,count); //前导0的处理很重要!!
		/*	if(a[i]>=1000000)
				cout<<a[i]/10000<<"-";		
			else if(100000<=a[i]&& a[i]<=999999)
				cout<<"0"<<a[i]/10000<<"-";
			else if(10000<=a[i]&& a[i]<=99999)
				cout<<"00"<<a[i]/10000<<"-";
			else 
				cout<<"000"<<"-";
			if(1000<=(a[i]%10000)&&(a[i]%10000)<=9999)
				cout<<a[i]%10000;
			else if(100<=(a[i]%10000)&&(a[i]%10000)<=999)
				cout<<"0"<<"-"<<a[i]%10000;
			else if(10<=(a[i]%10000)&&(a[i]%10000)<=99)
				cout<<"00"<<"-"<<a[i]%10000;
			else if(0<=(a[i]%10000)&&(a[i]%10000)<=9)
				cout<<"000"<<a[i]%10000;
			cout<<" "<<count<<endl;		
		*/
		}
	}
	if(flag==0)
		cout<<"No duplicates."<<endl; 
	getchar();  
	return 0;
} 

POJ1002 TLE求助!

04-28

代码有点长,delHyp()是删除输入串中的‘-’,changeStr()是全部转为‘0’-‘9’之间的字符,转换后之接冒泡排序的,可是一直超时;后来换了qsort()之后还是TLE,实在不知道什么地方效率低,还望高手指点……rnPS:总是很喜欢C++的动态分配,感觉这样空间不会浪费,不知道是不是因为这个耗费了太多时间哦?rn#include rn#include rnusing namespace std;rnrnvoid changeStr(string & a)rnrn int i = 0;rn int len = a.length();rn for (i = 0; i < len; i++)rn rn if (a[i] == 'A' || a[i] == 'B' || a[i] == 'C')rn a[i] = '2';rn else if (a[i] == 'D' || a[i] == 'E' || a[i] == 'F')rn a[i] = '3';rn else if (a[i] == 'G' || a[i] == 'H' || a[i] == 'I')rn a[i] = '4';rn else if (a[i] == 'J' || a[i] == 'K' || a[i] == 'L')rn a[i] = '5';rn else if (a[i] == 'M' || a[i] == 'N' || a[i] == 'O')rn a[i] = '6';rn else if (a[i] == 'P' || a[i] == 'S' || a[i] == 'R')rn a[i] = '7';rn else if (a[i] == 'T' || a[i] == 'U' || a[i] == 'V')rn a[i] = '8';rn else if (a[i] == 'W' || a[i] == 'X' || a[i] == 'Y')rn a[i] = '9';rn rnrnvoid delHyp(string & a)rnrn string::iterator it;rn for (it = a.begin(); it <= a.end(); it++)rn rn if (*it == '-')rn a.erase(it);rn rnrnint main()rnrn int n;rn cin >> n;rn string *str = new string[n];rn string *reStr = new string[n];rn int *flagStr = new int[n];rn int i = 0;rn for (i = 0; i < n; i++)rn rn cin >> str[i];rn delHyp(str[i]);rn changeStr(str[i]);rn flagStr[i] = 0;rn rn int j = 0;rn int Gflag = 0;rn for (i = 0; i < n; i++)rn rn if (flagStr[i] == 0)rn rn for (j = i + 1; j < n; j++)rn rn if (str[i] == str[j])rn rn flagStr[i]++;rn flagStr[j] = -1;rn Gflag = 1;rn rn rn rn rn if (Gflag == 0)rn cout << "No duplicates." << endl;rn elsern rn j = 0;rn for(i = 0; i < n; i++)rn rn if (flagStr[i] > 0)rn rn reStr[j] = str[i];rn flagStr[j] = flagStr[i];rn j++;rn rn rn int reStrlen = j;rn string temp;rn int flagTmp;rn for ( i = 0; i < reStrlen; i++)rn rn for (j = i + 1; j < reStrlen; j++)rn if (reStr[i] > reStr[j])rn rn temp = reStr[i];rn reStr[i] = reStr[j];rn reStr[j] = temp;rn flagTmp = flagStr[i];rn flagStr[i] = flagStr[j];rn flagStr[j] = flagTmp;rn rn rn for (i = 0; i < reStrlen; i++)rn rn for (j = 0; j < 3; j++)rn rn cout << reStr[i][j];rn rn cout << '-';rn for (j = 3; j < 7; j++ )rn cout << reStr[i][j];rn cout << ' ' << flagStr[i] + 1 << endl;rn rn rn delete []flagStr;rn delete []reStr;rn delete []str;rn return 0;rnrn

POJ1002郁闷,总是Wrong Answer

06-09

POJ论坛上的特殊数据跟样例数据都没有问题,可就是不过,郁闷了…………rn请各位大牛帮忙看一下,是那儿的问题?rnrn题目:rn487-3279rnTime Limit: 2000MS Memory Limit: 65536K rnTotal Submissions: 133774 Accepted: 22737 rnrnDescriptionrnrn企业喜欢用容易被记住的电话号码。让电话号码容易被记住的一个办法是将它写成一个容易记住的单词或者短语。例如,你需要给滑铁卢大学打电话时,可以拨打TUT-GLOP。有时,只将电话号码中部分数字拼写成单词。当你晚上回到酒店,可以通过拨打310-GINO来向Gino's订一份pizza。让电话号码容易被记住的另一个办法是以一种好记的方式对号码的数字进行分组。通过拨打必胜客的“三个十”号码3-10-10-10,你可以从他们那里订pizza。 rnrn电话号码的标准格式是七位十进制数,并在第三、第四位数字之间有一个连接符。电话拨号盘提供了从字母到数字的映射,映射关系如下: rnA, B, 和C 映射到 2 rnD, E, 和F 映射到 3 rnG, H, 和I 映射到 4 rnJ, K, 和L 映射到 5 rnM, N, 和O 映射到 6 rnP, R, 和S 映射到 7 rnT, U, 和V 映射到 8 rnW, X, 和Y 映射到 9 rnrnQ和Z没有映射到任何数字,连字符不需要拨号,可以任意添加和删除。 TUT-GLOP的标准格式是888-4567,310-GINO的标准格式是310-4466,3-10-10-10的标准格式是310-1010。 rnrn如果两个号码有相同的标准格式,那么他们就是等同的(相同的拨号) rnrn你的公司正在为本地的公司编写一个电话号码薄。作为质量控制的一部分,你想要检查是否有两个和多个公司拥有相同的电话号码。 rnrnInputrnrn输入的格式是,第一行是一个正整数,指定电话号码薄中号码的数量(最多100000)。余下的每行是一个电话号码。每个电话号码由数字,大写字母(除了Q和Z)以及连接符组成。每个电话号码中只会刚好有7个数字或者字母。rnOutputrnrn对于每个出现重复的号码产生一行输出,输出是号码的标准格式紧跟一个空格然后是它的重复次数。如果存在多个重复的号码,则按照号码的字典升序输出。如果输入数据中没有重复的号码,输出一行: rnNo duplicates. rnrnSample Inputrnrn12rn4873279rnITS-EASYrn888-4567rn3-10-10-10rn888-GLOPrnTUT-GLOPrn967-11-11rn310-GINOrnF101010rn888-1200rn-4-8-7-3-2-7-9-rn487-3279rnrnSample Outputrnrn310-1010 2rn487-3279 4rn888-4567 3rn

POJ1002遇到Time Limit Exceeded问题

03-20

做POJ1002时遇到Time Limit Exceeded这个问题,做出来是对的,就是把时间复杂度弄大了。。rn有朋友能帮我看看怎么改吗?谢谢。rnrn[code=C/C++]rn#include rn#include rn#include rn#include rn#include rnrnusing namespace std;rnrn// 建立hash表与号码数字键对照rnint map_hash[25]=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;rnrnrnint main()rnrn //char * Phone_num = new char;rn int cnt; // 输入数据的数目rn //cout << "input the phone number:" << endl;rn cin >> cnt ;rnrn vector Phone_set; //把输入输出存入vector里rn map Phone; //存放待输出的数据和个数rnrn // 处理数据rn while(cnt --)rn rn string temp; // 用来把数组转换成stringrn char Phone_num[20] = 0; rnrnrn cin >> Phone_num;rn int len = strlen(Phone_num); // 数组长度rnrn for(int i = 0; i != len; i++)rn rn if(Phone_num[i] != '-') rn rn if(Phone_num[i] >= 'A' && Phone_num[i] <= 'Z')rn Phone_num[i] = map_hash[Phone_num[i]-'A']+'0';rn else if(Phone_num[i] >= '0' && Phone_num[i] <= '9')rn ; //空语句rn rn else if(Phone_num[i] == '-') //当字符是"-"时rn rn int j; rn for( j = i; j != len;j ++)rn Phone_num[j] = Phone_num[j + 1];rn Phone_num[j] = 0; rn len--; rn i--; rn rnrn rn rn len = strlen(Phone_num); rnrn for(int j = len; j != 3; j-- )rn Phone_num[j] = Phone_num[j-1];rn Phone_num[3] = '-';rn rn temp = Phone_num; rn Phone_set.push_back(temp);rn //wtq[num_cnt] = Phone_num;rn //delete Phone_num; //rn rn //for(vector::iterator iter = Phone_set.begin(); iter != Phone_set.end(); iter++)rn //cout << *iter << endl;rn sort(Phone_set.begin(), Phone_set.end()); //按字典大小排序rn for(vector::iterator iter = Phone_set.begin(); iter != Phone_set.end(); iter++)rn ++Phone[*iter]; rn int print_num = 0; //查看重复次数rn for(map::iterator iter = Phone.begin(); iter != Phone.end(); iter++)rn rn if((*iter).second > 1)rn rn cout << (*iter).first << " " << (*iter).second << endl;rn print_num++;rn rn rn if(!print_num)rn cout << "No duplicates.";rnrn return 0;rnrn[/code]rnrn大家帮忙看看怎么改,代码有哪些不好的都希望朋友们能指出,谢谢!

有没有做ACM的?求救487-3279,poj1002

04-14

[code=C/C++]rn#includern#includern#includern#includernrnstruct phonern int times;rn int visited;rn struct phone * next[10];rn;rnrnint chset[]= 2,2,2,rn 3,3,3,rn 4,4,4,rn 5,5,5,rn 6,6,6,rn 7,0,7,7,rn 8,8,8,rn 9,9,9,0;rnrnint han(char c)//转换为标准格式字符rn if(c>='0'&&c<='9')rn return c-48;rn if(c>='A'&&c<='Z')rn return chset[(c-65)];rn return -1;rnrnrnstruct phone * create()//初始化一个节点rn struct phone * t=(struct phone *)malloc(sizeof(struct phone));rn for(int i=0;i<10;i++)rn t->times=0;rn t->next[i]=0;rn t->visited=0;rn rn return t;rnrnrnstruct phone * head=create();//头结点rnrnchar s[7]="0";//存储标准格式号码rnint flag=0,times=0;rnrnvoid print(struct phone * p,int d)rn int i=0;rn p->times--;rn while((!p->next[i]))rn i++;rn rn if(d==7)rn if(p->visited)rn flag=1;rn return;rn rn p->visited=1;rn s[6]=i+48;rn times=p->times+1;//找到一个出现超过1次的号码,次数为timesrn return;rn rn if(p->next[i]->times<2)rn p->next[i]=0;rn flag=1;//此节点小于2次flag=1rn return;rn rn print(p->next[i],++d);rn if(flag)rn return;rn rn p->visited=1;rn s[d-2]=i+48;rn return;rnrnrnint main()rn struct phone *p = head, * tp;rn int n,i,j,t,NOans=1;rn char c;rn freopen("in.txt", "r", stdin);rn scanf("%d",&n);getchar();rn for(i=1;i<=n;i++)rn for(j=1;j<=7;j++)rn c=getchar();rn while(han(c)==-1)rn c=getchar();rn t=han(c);rn p->times+=1;rn if(p->next[t]==0)rn p->next[t]=create();rn rn p=p->next[t];rn rn p=head;rn rn while(p->times>1)rn print(p,1);rn if(!flag)rn for(int k=0;k<7;k++)rn if(k==3)rn printf("-");rn rn printf("%d",(int)s[k]-48);rn NOans=0;rn rnrn printf(" %d\n",times);rn memset(s,0,sizeof(s));rn times=0;rn rn flag=0;//重置flagrn rn if(NOans)rn printf("No duplicates.\n");rn rn return 0;rnrn[/code]rn希望大大们给出我这个算法的错误之处,别的方法我知道,我就只想知道这个算法是哪里不对了。

有关poj1002的问题,可以AC但编译器通过不了

11-03

这是网上的解答:rn#include rn#include rn#include rnrnchar map[26] = '2', '2', '2', '3', '3', '3', '4', '4', '4', rn '5', '5', '5', '6', '6', '6', '7', '7', '7', rn '7', '8', '8', '8', '9', '9', '9', '9';//按键映射表rnrnchar phone[100000][9]; //全部电话号码rnrnint n; //电话号码的数量rnrnchar number[80]; //一个未经处理的电话号码rnrnrnint main(void)rnrn int loop; //循环变量rnrn int phone_i=0, phone_j=0; //phone数组的下标rnrn int tag = 0; //重复标志,0没有处于一个重复,1有重复rnrn int count = 1; //重复次数rnrnrn scanf("%d", &n);rnrn for(phone_i=0; phone_i='0' && number[loop]<='9')//当前字符是数字rnrn phone[phone_i][phone_j] = number[loop];rn rn else if(number[loop]>='A' && number[loop]<='Z')//当前字符是大写字母rnrn phone[phone_i][phone_j] = map[number[loop]-'A'];rn rn else if(number[loop] == '-')//忽略'-'rnrn continue;rn rn phone_j++;rn rn phone_j = 0;rn rn rn //排序全部电话号码rnrn [color=#FF0000]qsort(phone, n, 9, strcmp);rn[/color]rn for(loop=1; loop 1)rn printf("%s %d\n", phone[loop-1], count);rn rn count = 1;rn rn rn [color=#008000]if(count > 1)//查看最后一条记录是否有重复rnrn printf("%s %d\n", phone[loop-1], count);rn [/color]rn if(!tag) rn printf("No duplicates.\n");rn return 0;rnrn红字部分无法通过vs编译rntypedef int(*func)(const void*, const void*);rn qsort(phone, n, 9, (func)strcmp);rn强行类别转换后能通过编译,结果也正确但却CE了,什么情况?rn还有请教一下qsort的二维数组排序不应该是这样的吗?为什么qsort(phone, n, 9, (func)strcmp)就行?rnqsort(a,1000,sizeof(int)*2,comp);rnint comp(const void*a,const void*b)rnrn return((int*)a)[0]-((int*)b)[0];rnrn还有绿色部分看不懂,帮忙解答一下

没有更多推荐了,返回首页

私密
私密原因:
请选择设置私密原因
  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他
其他原因:
120
出错啦
系统繁忙,请稍后再试

关闭