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 }