UVa 755
題目
http://domen111.github.io/UVa-Easy-Viewer/?755
有 $n$ 個電話號碼,我們規定一個電話號碼的標準格式是 3個數字
-
4個數字
例如 1234-567
就是一個合法的電話號碼
另外,我們的撥號鍵都會有相對應的英文字母,有時候我們也會用這些英文字母來記憶電話號碼
至於 -
開心放多少個就放多少個,但是合法的電話號碼表示中只會在第 3 和第 4 個數字之間有 -
現在給你很多雜亂的電話號碼,請你幫忙全部轉換成合法的電話號碼格式,並且找出重複出現的電話號碼分別都是現了幾次
想法 By Koios
轉換成合法字串並不困難,我們可以先忽視其中的所有 -
,當數字到了 3 個之後再自行加入
並且把所有的英文字母轉換成相對應的數字即可
轉換成合法字串後,要找到重複的字串可以用排序來解決
排序後的序列,會使得相同的字串會被排在一起,那麼我們就只需要再掃過檢查重複即可
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| #include<iostream> #include<algorithm> using namespace std; int t, n; bool out=false;
string s, arr[100010];
string tbl = "22233344455566677778889999"; int main(){ cin>>t; while(t--){ if(out) cout<<"\n"; else out=true; cin>>n; for(int i=0 ; i<n ; i++){ cin>>s; arr[i] = ""; for(int j=0, k=0 ; j<s.size() ; j++){ if(s[j] != '-'){ if(s[j]>='0' && s[j]<='9') arr[i] += s[j]; else if(s[j]>='A' && s[j]<='Z') arr[i] += tbl[s[j]-'A']; k++; if(k == 3) arr[i] += '-'; } } } sort(arr, arr+n); bool find_ans=false; for(int i=0, j ; i<n ; i=j){ for(j=i+1 ; j<n ; j++){ if(arr[i] != arr[j]) break; } if(j != i+1){ cout<<arr[i]<<" "<<j-i<<"\n"; find_ans=true; } } if(!find_ans) cout<<"No duplicates.\n"; } return 0; }
|
時間複雜度分析
每筆測資輸入時間複雜度為 $O(n)$
每筆測資預處理 $arr$ 時間複雜度為 $O(\sum_{i=0}^{n-1}{len(s)})$
每筆測資排序時間複雜度為 $O(nlogn)$
每筆測資找重複元素的時間複雜度為 $O(n)$
總時間複雜度為 $t(2n + nlogn + \sum_{i=0}^{n-1}{len(s)})$