15. 電話號碼問題成績: 10 / 折扣: 0.8
商業單位需要容易記憶的電話號碼,有一些方法可以讓電話號碼變得更容易記憶。譬如,可以把電話號碼寫成單詞或短語,如 MON-GLOP 可以代表滑鐵盧大學的電話。有時僅僅是把號碼的一部分寫成單詞,如打 310-GINO 便可向 GINO 比薩餅店定購比薩。另一種讓電話號碼容易記憶的方法是將數字用一種容易記的方式組合起來,譬如 3-10-10-10 也可以代表 GINO 比薩餅店。
電話號碼的標準形式是七位十進位數字,在它的第三位和第四位之間用連字號串連(例如:666-1200)。電話的鍵盤提供了字元與數字之間的映射關係,如下所示:
| 2 |
A、B和C |
| 3 |
D、E和F |
| 4 |
G、H和I |
| 5 |
J、K和L |
| 6 |
M、N和O |
| 7 |
P、R和S |
| 8 |
T、U和V |
| 9 |
W、X和Y |
Q 和 Z 沒有映射到鍵盤,而連字號不需要被撥打併且可以根據需要添加和刪除。MON-GLOP 的標準形式是 666-4567,310-GINO 的標準形式是310-4466,3-10-10-10的標準形式也是 310-1010。
如果兩個電話號碼有相同的標準形式,那麼這兩個電話號碼是相同的。
你所在的公司正在編輯一本當地商業單位的電話簿,作為品質控制流程的一部分,你需要確認在該電話簿中有沒有錯誤的電話號碼,以及有沒有兩個(或兩個以上的)商業單位使用相同的電話號碼。由於當地只使用了 3 和 6 兩個區段,因此電話號碼的第一個數字應當永遠是 3 或者 6,如果出現了其它數字,就表示這個電話號碼錯了。此外,如果電話號碼中出現了 Q 和 Z,也說明這個電話錯了。
輸入
一次輸入為一個範例。每個號碼一行,由一組包含十進位數、大寫字母(Q、Z 除外)和連字號的字串組成(每行的字元不會超過 20 個)。每次輸入的資料可能會非常大,譬如超過 1,000,000 個電話號碼。
你可以假設輸入中可能會出現重複的電話號碼不超過 1,500 個,每個號碼重複的次數不超過 1000 次。
輸出
輸出包括兩個部分,第一個部分是錯誤的電話號碼,對於這些號碼應當按照輸入的順序以原始的形式輸出。在輸出錯誤電話號碼前輸出“Error:”,隨後輸出這些號碼,如果沒有錯誤的電話號碼,則輸出“Not found.”。
第二部分是重複的電話號碼,對每一個在電話簿中以任何形式出現一次以上的電話號碼,產生一行輸出。這一行應以標準形式給出電話號碼,其後跟隨一個空格,空格後跟隨電話號碼在電話簿中出現的次數。所有重複的電話號碼輸出行應以號碼的升序排列(小號碼在前)。在輸出重複電話號碼前輸出“Duplication”,隨後按照上述格式輸出號碼,如果在輸入中沒有重複的電話號碼,則輸出:“Not found.”。
注意
你所編寫的程式以後可能會在一種特殊的嵌入式裝置上運行,為了降低成本,這種裝置使用的 CPU 不是很快、可用的 RAM 為 288K(跟 GBA 一樣)且它沒有磁碟裝置因此不能使用檔案作為資料的臨時儲存。
提示
請參考《編程珠璣》第一部分,若程式不能在規定的記憶體中運行,則不得分。
#include<stdio.h>#include<string.h>#include<malloc.h>long count[1600];long pows(int b,int x);long trans(char a[]);int checkerror(char a[]);void compositor(long st[],int q);void main(){char a[15];int flag=0,flag1=0,i,q=0;long d,st[1600];printf("Error:\n");while(gets(a)!=NULL){if( checkerror(a) ){d=trans(a);for(i=0;i<=q;i++){if(d==st[i]){count[i]++;break;}}if(i>q){st[i]=d;q++;}}else{printf("%s\n",a);flag=1;}}if(!flag)printf("Not found.\n");printf("\n");compositor(st,q);printf("Duplication:\n");for(i=0;i<=q;i++){if(count[i]!=0){printf("%ld",st[i]/10000);printf("-");printf("%.4ld",st[i]%10000);printf(" ");printf("%d\n",count[i]+1);flag1=1;}}if(!flag1)printf("Not found.\n");}int checkerror(char temp[15]){int i=0,len;len=strlen(temp);for(i=0;i<len;i++) { if(temp[i]==45) continue; if((temp[i]>=68&&temp[i]<=70)||(temp[i]>=77&&temp[i]<=79)||(temp[i]==51)||(temp[i]==54)) return 1; else return 0; }return 0;}long trans(char temp[]){int b[10],d=0,i,len,q=0;len=strlen(temp);for(i=0;i<len;i++) { if(temp[i]==45) continue; if(temp[i]>=65&&temp[i]<=67) {b[q]=2;q++;continue;} if(temp[i]>=68&&temp[i]<=70) {b[q]=3;q++;continue;} if(temp[i]>=71&&temp[i]<=73) {b[q]=4;q++;continue;} if(temp[i]>=74&&temp[i]<=76) {b[q]=5;q++;continue;} if(temp[i]>=77&&temp[i]<=79) {b[q]=6;q++;continue;} if(temp[i]>=80&&temp[i]<=83) {b[q]=7;q++;continue;} if(temp[i]>=84&&temp[i]<=86) {b[q]=8;q++;continue;} if(temp[i]>=87&&temp[i]<=89) {b[q]=9;q++;continue;} else {b[q]=temp[i]-48;q++;continue;} } for(q=0;q<7;q++) d=d+ pows(b[q],6-q);return d;}long pows(int b,int x){int i;long t=1;for(i=0;i<x;i++)t*=10;return b*t;}void compositor(long st[],int q){int i,j,k;long temp;for(i=0;i<=q-1;i++){k=i;for(j=k;j<=q;j++){if(st[k]>st[j])k=j;}if(k!=i){temp=st[k];st[k]=st[i];st[i]=temp;temp=count[k];count[k]=count[i];count[i]=temp;}}}