B. Hyperset


http://codeforces.com/contest/1287/problem/B

 

思路:

倆倆配對確定唯一的第三張就可以。每一張卡片可以用64為整數表示,所以找第三張就是找這個整數有沒有。找第三張卡片不能用哈希map,因為有輸入數據會導致重復的key比較多,導致超時。回憶起了當年自己為什么堅持用紅黑樹map。

兩個卡片確定第三個可以用位運算提高效率,不過暴力計算也可以過。

 

 1 #include <iostream>
 2 #include <string>
 3 #include <stdio.h>
 4 #include <algorithm>
 5 #include <map>
 6 #include <unordered_map>
 7 #include <set>
 8 #include <string.h>
 9  
10 using namespace std;
11  
12 typedef long long LL;
13  
14 const int N = 1501;
15 int n,m;
16 string str[N];
17 LL sm2[N];
18 LL sm3[N];
19  
20 inline LL fb3(char c)
21 {
22     if (c == 'S')
23     {
24         return 1;
25     }
26     if (c == 'E')
27     {
28         return 2;
29     }
30     return 3;
31 }
32 inline LL fb2(char c)
33 {
34     if (c == 'S')
35     {
36         return 0;
37     }
38     if (c == 'E')
39     {
40         return 0;
41     }
42     return 3;
43 }
44  
45 LL fun(const string& s, int index)
46 {
47     LL k2 = 0;
48     LL k3 = 0;
49     for (int i = 0; i < m; ++i)
50     {
51         k2 |= (fb2(s[i]) << (i<<1));
52         k3 |= (fb3(s[i]) << (i<<1));
53     }
54     sm2[index] = k2;
55     sm3[index] = k3;
56     return k3;
57 }
58  
59 inline LL fun(LL s3_1, LL s3_2, LL s2_1, LL s2_2)
60 {
61     return (s3_1^s3_2) | (((~s2_1)^s2_2)&(s3_1|s3_2));
62 }
63  
64 int main()
65 {
66     while(cin>>n>>m)
67     {
68         set<LL> s_t;
69         for (int i = 0; i < n; ++i)
70         {
71             cin>>str[i];
72             s_t.insert(fun(str[i], i));
73         }
74  
75         int ans = 0;
76         for (int i = 0; i < n; ++i)
77         {
78             for (int j = i + 1; j < n; ++j)
79             {
80                 if (s_t.find(fun(sm3[i], sm3[j], sm2[i], sm2[j])) != s_t.end())
81                 {
82                     ans++;
83                 }
84             }
85         }
86         cout <<(ans/3) << endl;
87     }
88     return 0;
89 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM