POJ 3283 - Card Hands
http://poj.org/problem?id=3283
概要
n 人分のカードの集合をそれぞれ連結リストで管理している.
共通の tail を持っている場合,その部分を共有することでノード数を減らしてメモリを節約できるようになる.
与えられたデータを持つのに必要な最小のノード数を答える.
制約
- カードの枚数の合計 <= 10^5
解法
後ろからトライ木を作ってノード数を数えればいい.
真面目にトライ木を作るのが面倒だったので map でやったら 1000MS でギリギリ通った.
poj/3283.cc1 #include <iostream> 2 #include <vector> 3 #include <map> 4 #include <algorithm> 5 using namespace std; 6 7 int c2i(const string& s) 8 { 9 int n; 10 switch (s[s.size()-1]) { 11 case 'C': n = 0; break; 12 case 'D': n = 1; break; 13 case 'H': n = 2; break; 14 case 'S': n = 3; break; 15 default: throw s; 16 } 17 n *= 13; 18 switch (s[0]) { 19 case 'A': n += 1; break; 20 case '2' ... '9': n += s[0]-'0'; break; 21 case '1': n += 10; break; 22 case 'J': n += 11; break; 23 case 'Q': n += 12; break; 24 case 'K': n += 13; break; 25 default: throw s; 26 } 27 return n; 28 } 29 30 struct trie 31 { 32 map<int,trie> m; 33 typedef vector<int>::const_iterator Iterator; 34 35 void insert(Iterator it, const Iterator& last) 36 { 37 if (it == last) { 38 return; 39 } 40 const int n = *it; 41 ++it; 42 m[n].insert(it, last); 43 } 44 45 int size() const 46 { 47 int r = 1; 48 for (map<int,trie>::const_iterator it = m.begin(); it != m.end(); ++it) { 49 r += it->second.size(); 50 } 51 return r; 52 } 53 }; 54 55 int main() 56 { 57 ios::sync_with_stdio(false); 58 int N; 59 while (cin >> N && N != 0) { 60 trie t; 61 for (int i = 0; i < N; i++) { 62 int K; 63 cin >> K; 64 vector<int> cards; 65 for (int i = 0; i < K; i++) { 66 string s; 67 cin >> s; 68 cards.push_back(c2i(s)); 69 } 70 sort(cards.rbegin(), cards.rend()); 71 t.insert(cards.begin(), cards.end()); 72 } 73 cout << t.size()-1 << endl; 74 } 75 return 0; 76 }