1002 -- 487-3279

http://poj.org/problem?id=1002

RE、MLE、TLE、WA吃了个遍。听网上有人说超时TLE是因为快排最糟时O(n^2)的时间复杂度,还把一直不愿意学的堆排序给好好实现了下。结果,最后用的还是用的库函数qsort。重点是:把输入的数据处理成整数,字符串不行!

  1 /*http://poj.org/showmessage?message_id=349192
  2 感谢提示。TLE.
  3 我的算法一开始是处理完一个字符串,就去寻找是否已经有相同的字符串,然后数目加1,
  4 后来发现当字符串数目很大(比如100000)这么做简直。。不说了,估计那个程序到现在也没跑完。
  5 后来改成直接记录,然后用sort排序,再从前向后搜相同的整数(也就是相同的字符串)
  6 不过在POJ上数据规模有点大,用字符串老超时,还得换成整数形式才A了。。。第一种是string(TLE了)*/
  7 #include<stdio.h>
  8 #include<string.h>
  9 int theNumberOfTelephoneNumbers,size/*result数组的有效长度*/,telephoneNumbers,result[100500],flagPrint;
 10 char telephoneNumbersTmp[100];
 11 /*MLE.telephoneNumbersTmp,telephoneNumbers数组调小
 12 RE.the number of telephone numbers in the directory (up to 100,000)
 13 原来1000的数组开小了*/
 14 /*
 15 typedef struct heap
 16 {
 17     int* arr;//指向存放堆数据的数组
 18     int heapMaxIndex;
 19     int arrLength;
 20 } heap;*/
 21 /*
 22 void maxHeapify(heap *hp,unsigned int i)
 23 {
 24     *//*第二步:保持堆的性质。
 25     这一步是堆排序的基础。这里将功能写成一个函数名为void maxHeapify(Heap *hp, unsigned int nodei),
 26     这个函数用于让一个数组变成一个符合堆性质的数组。时间复杂度为O(h),h是堆所属二叉树树的高度=log2n(n是节点个数)。
 27     思想是:从一个节点i,和他的孩子leftchild(i),rightChild(i)中找到最大的,然后其索引存放在largest中。
 28     如果i是最大的。那么i为根的子树已经是最大堆,程序结束。
 29     否则i的某个子节点有最大元素,那么i的值和largest的值交换。下标为largest的节点在交换后作为父节点,
 30     那么他可能又违反堆性质,因此递归调用该函数。*//*
 31     unsigned int l=(i+1)<<1-1*//*left child:2*i-1*//*,r=(i+1)<<1*//*right child:2*i*//*,largest=0;
 32     int tmpInt;
 33     int heapMaxI=hp->heapMaxIndex;
 34     //比较左孩子节点和当前节点的大小
 35     if(l<=heapMaxI&&hp->arr[l]>hp->arr[i])
 36     {
 37         largest=l;
 38     }
 39     else
 40     {
 41         largest=i;
 42     }
 43     //比较左孩子节点和当前节点中较大者(largest)与右孩子节点的大小
 44     if(r<=heapMaxI&&hp->arr[r]>hp->arr[largest])
 45     {
 46         largest=r;
 47     }
 48     if(largest!=i)
 49     {
 50         tmpInt=hp->arr[largest];
 51         hp->arr[largest]=hp->arr[i];
 52         hp->arr[i]=tmpInt;
 53         maxHeapify(hp,largest);
 54     }
 55 }*//*
 56 heap* createHeap(int* arr,int arrLength,heap *hp)
 57 {
 58     *//*第三步 利用maxHeapify函数创建堆
 59     对于1个个数为n的堆,从上面堆的图中可以分析得到,n/2-1之前(包含n/2-1)的都是父节点。
 60     之后的都是叶子节点,我们只需要对父节点进行maxHeapify就可以了。
 61     n/2可以用右移运算n>>1。*//*
 62     int i;
 63     hp->arr=arr;
 64     hp->heapMaxIndex=arrLength-1;
 65     hp->arrLength=arrLength;
 66     for(i=arrLength>>1-1; i>=0; i--)
 67     {
 68         maxHeapify(hp,i);
 69     }
 70     return hp;
 71 }*//*
 72 void heapSort(heap *hp)
 73 {
 74     *//*第四步:堆排序
 75     设堆的数组为A[0..n-1],调用maxHeapify函数就可以得到最大值,然后将最大值和n-1互换,把堆的大小heapMaxIndex减1,
 76     再次调用maxHeapify,又得到最大值,存放在A[0],再和A[n-2]互换,把堆的大小再减一,这样循环下去,知道堆的大小为0。
 77     那么我们就得到了由小到大的排好序的数组。*//*
 78     int last,tmpInt;
 79     while(hp->heapMaxIndex>0)
 80     {
 81         last=hp->heapMaxIndex;
 82         tmpInt=hp->arr[last];
 83         hp->arr[last]=hp->arr[0];
 84         hp->arr[0]=tmpInt;
 85         hp->heapMaxIndex--;
 86         maxHeapify(hp,0);
 87     }
 88 }*/
 89 void dealTelephoneNumbers()
 90 {
 91     int i=0;
 92     telephoneNumbers=0;
 93     while(telephoneNumbersTmp[i]!='\0') //可能有0~9、A~P、R~Y、-
 94     {
 95         //printf("2-------%d\n",telephoneNumbers);
 96         if(telephoneNumbersTmp[i]>='A'&&telephoneNumbersTmp[i]<='P')
 97         {
 98             telephoneNumbers*=10;
 99             telephoneNumbers+=(telephoneNumbersTmp[i]-'A')/3+2;
100             //'A'(0)    'B'(1)      'C'(2) -- 2
101             //'D'(3)    'E'(4)      'F'(5) -- 3
102             //'G'(6)    'H'(7)      'I'(8) -- 4
103             //'J'(9)    'K'(10)     'L'(11)-- 5
104             //'M'(12)   'N'(13)     'O'(14)-- 6
105             //'P'(15)   -- 7
106             //'R'(17)   'S'(18) -- 7
107             //'T'(19)   'U'(20)     'V'(21)--8
108             //'W'(22)   'X'(23)     'Y'(24)--9[没有Q、Z]
109         }
110         else if(telephoneNumbersTmp[i]>='R'&&telephoneNumbersTmp[i]<='Y')
111         {
112             telephoneNumbers*=10;
113             telephoneNumbers+=(telephoneNumbersTmp[i]-'A'-1)/3+2;
114         }
115         else if(telephoneNumbersTmp[i]>='0'&&telephoneNumbersTmp[i]<='9')
116         {
117             telephoneNumbers*=10;
118             telephoneNumbers+=telephoneNumbersTmp[i]-'0';
119         }
120         i++;
121     }
122     //printf("2-------%d\n",telephoneNumbers);
123     /*i=0;
124     while(telephoneNumbersTmp[i]!='\0'){
125         printf("%c",telephoneNumbersTmp[i]);
126         i++;
127     }
128     printf("\n");*/
129 }
130 int cmp (const void *a,const void *b)
131 {
132     return *(int *)a-*(int *)b;
133 }
134 int main()
135 {
136     int i,j,k/*j指向多个相同字符串的第一个,k指向多个相同字符串的最后一个*/,t;
137     //heap hp,*hpPoint;
138     //freopen("test.in", "r", stdin);
139     while(scanf("%d",&theNumberOfTelephoneNumbers)!=EOF)
140     {
141         size=flagPrint=telephoneNumbers=0;
142         for(i=0; i<theNumberOfTelephoneNumbers; i++)
143         {
144             //printf("%d ",i);
145             scanf("%s",telephoneNumbersTmp);
146             //printf("1-------%s",telephoneNumbersTmp);
147             dealTelephoneNumbers();
148             result[size++]=telephoneNumbers;
149         }
150         //qsort(result,size,sizeof(result[0]),cmpStr);快排最糟的时间复杂度是n^2,不稳定
151         /*for(i=0;i<size;i++){
152             printf("1.%d==%d\n",i,result[i]);
153         }
154         printf("size:%d\n",size);*/
155         //hpPoint=createHeap(result,size,&hp);
156         /*for(i=0;i<size;i++){
157             printf("2.%d==%d\n",i,result[i]);
158         }*/
159         //heapSort(hpPoint);
160         qsort(result,size,sizeof(int),cmp);
161         /*for(i=0; i<size; i++)
162         {
163             printf("3.%d==%d\n",i,result[i]);
164         }
165         printf("size:%d\n",size);*/
166         for(i=0,j=1; i<size;)
167         {
168             //printf("i:%d-%d j:%d-%d\n",i,result[i],j,result[j]);
169             if(result[i]!=result[j])
170             {
171                 //printf("i:%d-%d j:%d-%d\n",i,result[i],j,result[j]);
172                 if(j-i>1)
173                 {
174                     printf("%03d-%04d %d\n",result[i]/10000,result[i]%10000,j-i);
175                     flagPrint=1;
176                 }
177                 i=j;
178             }
179             j++;
180         }
181         if(flagPrint==0)
182         {
183             printf("No duplicates. \n");
184         }
185     }
186     return 0;
187 }

 

转载于:https://www.cnblogs.com/JXNU-WuYeqi/articles/5378705.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值