POJ 2973 - Scrabble
http://poj.org/problem?id=2973
概要
1つのパターンに対して n 個の文字列が与えられる. パターン中のワイルドカードはどの文字にも一致するとみなす. パターンの文字を好きな数だけ好きな順番で並べた文字列が一致するとき,その文字列にマッチするとする.
n 個の文字列のうち,いくつパターンにマッチするか答える.
制約
- 1 <= n <= 1000
- 1 <= 文字列およびパターンの長さ <= 7
解法
文字列中の各文字 c について,c の出現回数がパターンのそれより多い場合はいくつ多いかを数え,その総計がワイルドカードの数以下だったらマッチする,というように実装した.
poj/2973.cc1 #include <iostream> 2 #include <vector> 3 using namespace std; 4 5 bool match(const vector<int>& s, const vector<int>& c, int wild) 6 { 7 for (int i = 0; i < 26; i++) { 8 if (s[i] > 0) { 9 if (s[i] > c[i]) { 10 wild -= s[i] - c[i]; 11 if (wild < 0) { 12 return false; 13 } 14 } 15 } 16 } 17 return true; 18 } 19 20 int main() 21 { 22 int N; 23 while (cin >> N && N != 0) { 24 vector<vector<int> > dict; 25 for (int i = 0; i < N; i++) { 26 string word; 27 cin >> word; 28 vector<int> c(26, 0); 29 for (string::const_iterator it(word.begin()); it != word.end(); ++it) { 30 ++c[*it - 'A']; 31 } 32 dict.push_back(c); 33 } 34 string tile; 35 cin >> tile; 36 int wild = 0; 37 vector<int> c(26, 0); 38 for (string::const_iterator it(tile.begin()); it != tile.end(); ++it) { 39 if (*it == '_') { 40 ++wild; 41 } else { 42 ++c[*it-'A']; 43 } 44 } 45 int ans = 0; 46 for (vector<vector<int> >::const_iterator it(dict.begin()); it != dict.end(); ++it) { 47 if (match(*it, c, wild)) { 48 ++ans; 49 } 50 } 51 cout << ans << endl; 52 } 53 return 0; 54 }