UVa 10393

UVa 10393

題目

http://domen111.github.io/UVa-Easy-Viewer/?10393

給定每個手指在鍵盤上可以輸入的字元

現在有一個人有幾個手指頭受傷沒辦法打特定的字,給一群字串,問所有字串中他可以打出來,並且長度最長的字串有多少個?分別是哪些?

輸出請以字典序大小由小到大輸出,並且每個字串都只能至多出現一次

想法

我們可以用 bit 去分別記錄特定手指可以寫的字

輸入會告訴我們哪些手指不能用,那我們可以先把不能用的手指可以打得字以位元記錄下來,再反轉後就變成可以打的

實作上可以跟所有可行字元組成的數字 xor 來處理

到目前我們有了當前這個人可以打哪些字元這項資訊,那麼最後只需要判斷每個字是否可以被打出來,然後找出最長的長度即可

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//By Koios1143
#include<iostream>
#include<algorithm>
using namespace std;
string dict = "qazwsxedcrfvtgb yhnujmik,ol.p;/";
string fig[11] = {"", "qaz", "wsx", "edc", "rfvtgb", " ", " ", "yhnujm", "ik,", "ol.", "p;/"};
string s[1005];
int tbl[128], alltype[32];
int all=0, F, N, cantype, ans, len;
bool res[1005];

int str_to_num(string s){
int ret = 0;
for(int i=0 ; i<s.size() ; i++){
ret |= (1<<tbl[s[i]]);
}
return ret;
}

int main(){
// 預處理建表
for(int i=0 ; i<dict.size() ; i++){
tbl[dict[i]] = i;
}
for(int i=1 ; i<=10 ; i++){
// alltype 表示該手指能寫的字元
for(int j=0 ; j<fig[i].size() ; j++){
alltype[i] |= (1<<tbl[fig[i][j]]);
}
// all 表示全部可以寫的字元
all |= alltype[i];
}

while(cin>>F>>N){
cantype = ans = len = 0;
for(int i=0, f ; i<F ; i++){
cin>>f;
// 先找出不能打的字元
cantype |= alltype[f];
}
// 接下來用 xor 轉換成可以打的字元
cantype ^= all;

for(int i=0 ; i<N ; i++){
cin>>s[i];
}

// 輸出需要依照字母序排序
sort(s, s+N);
// 以 res 紀錄該字串是否可以被打出來
for(int i=0, num, sz ; i<N ; i++){
// 忽略已經出現過的字串
if(i>0 && s[i] == s[i-1]){
res[i] = false;
continue;
}
num = str_to_num(s[i]);
sz = s[i].length();

// 可以被打出來的情況
if((num & cantype) == num){
res[i] = true;
if(sz > len){
len = sz;
ans = 1;
}
else if(sz == len){
ans++;
}
}
else{
res[i] = false;
}
}
cout<<ans<<"\n";
// 最後找出可以打的字串中長度是最長的字串
for(int i=0 ; i<N ; i++){
if(res[i] && s[i].length() == len){
cout<<s[i]<<"\n";
}
}
}
return 0;
}

時間複雜度分析

每筆測資輸入時間複雜度為 $O(N)$

每筆測資排序時間複雜度為 $O(NlogN)$

每筆測資找可以被打出來的字串所需時間複雜度為 $O(N)$

每筆測資找答案時間複雜度為 $O(N)$

每筆測資總時間複雜度為 $O(N + NlogN)$