[Offer收割]编程练习赛56

A.片游戏

暴力

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 map<int, int> mp;
 4 set<int> S;
 5 const int maxn = 1e5 + 10;
 6 int A[maxn], B[maxn];
 7 
 8 int main(){
 9     int N, ans = 1;
10     scanf("%d", &N);
11     for(int i = 1; i <= N; ++i) scanf("%d", A + i), mp[A[i]]++;
12     for(int i = 1; i <= N; ++i) scanf("%d", B + i);
13     for(int i = 1; i <= N + 1; ++i) if(mp.find(i) == mp.end()) S.insert(i);
14     for(int i = 1; i <= N; ++i){
15         mp[A[i]]--;
16         if(mp[A[i]] == 0) S.insert(A[i]);
17         mp[B[i]]++;
18         if(mp[B[i]] == 1 && S.find(B[i]) != S.end()) S.erase(B[i]);
19         ans = max(ans, *S.begin());
20         mp[B[i]]--;
21         if(mp[B[i]] == 0) S.insert(B[i]);
22         mp[A[i]]++;
23         if(mp[A[i]] == 1 && S.find(A[i]) != S.end()) S.erase(A[i]);
24     }
25     printf("%d
", ans);
26     return 0;
27 }
Aguin

B.藏坐标

暴力

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 vector<string> cal(string s){
 5     int l = s.length();
 6     vector<string> ret;
 7     if(l == 1 && s[0] == '0' || s[0] != '0') ret.push_back(s);
 8     for(int i = l - 1; i > 0; --i){
 9         if(s[l-1] != '0' && (s[0] != '0' || i == 1)) ret.push_back(s.substr(0, i) + '.' + s.substr(i, l - i));
10     }
11     return ret;
12 }
13 
14 typedef pair<string, string> pii;
15 vector<pii> ans;
16 
17 int main(){
18     char s[11];
19     scanf("%s", s);
20     int l = strlen(s);
21     for(int i = 0; i < l - 1; ++i){
22         string a = string(s).substr(0, i + 1);
23         string b = string(s).substr(i + 1);
24         vector<string> v1 = cal(a), v2 = cal(b);
25         for(int j = v1.size() - 1; j >= 0; j--)
26             for(int k = v2.size() - 1; k >= 0; k--)
27                 ans.push_back(pii(v1[j], v2[k]));
28     }
29     sort(ans.begin(), ans.end());
30     for(int i = 0; i < ans.size(); ++i) cout << ans[i].first << ',' << ans[i].second << endl;
31     return 0;
32 }
Aguin

C.品分类

启发式合并

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 1e5 + 10;
 4 
 5 set<int> ih[maxn];
 6 set<int> :: iterator it;
 7 int fa[maxn];
 8 int Find(int x){
 9     return fa[x] == x ? x : fa[x] = Find(fa[x]);
10 }
11 void Union(int x, int y){
12     x = Find(x), y = Find(y);
13     if(x == y) return;
14     if(ih[x].size() > ih[y].size()) swap(x, y);
15     for(it = ih[x].begin(); it != ih[x].end(); ++it){
16         ih[y].insert(*it);
17         ih[*it].erase(x);
18         ih[*it].insert(y);
19     }
20     fa[x] = y;
21 }
22 
23 int main(){
24     int N, M;
25     scanf("%d %d", &N, &M);
26     for(int i = 1; i <= N; ++i) fa[i] = i;
27     for(int i = 1; i <= M; ++i) {
28         char op[11];
29         scanf("%s", op);
30         if(op[0] == 'R'){
31             int x, y, o;
32             scanf("%d %d %d", &x, &y, &o);
33             if(o == 1) Union(x, y);
34             else {
35                 x = Find(x), y = Find(y);
36                 ih[x].insert(y), ih[y].insert(x);
37             }
38         }
39         else {
40             int x, y;
41             scanf("%d %d", &x, &y);
42             x = Find(x), y = Find(y);
43             if(x == y) puts("1");
44             else if(ih[y].find(x) != ih[y].end()) puts("2");
45             else puts("3");
46         }
47     }
48     return 0;
49 }
Aguin

D.的观测

线段树

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int maxn = 5e4 + 10;
 5 LL a[maxn];
 6 
 7 vector<LL> Union(vector<LL> A, vector<LL> B) {
 8     for (int i = 0; i <= 60; i++) {
 9         if(!B[i]) continue;
10         for (int j = 0; j <= 60; ++j) {
11             if (((B[i]) & (1LL << j)) == 0) continue;
12             if (!A[j]) {
13                 A[j] = B[i];
14                 break;
15             }
16             else B[i] ^= A[j];
17         }
18     }
19     return A;
20 }
21 
22 vector<LL> T[maxn<<2], S;
23 inline void gather(int p)
24 {
25     T[p] = Union(T[p<<1], T[p<<1|1]);
26 }
27 void build(int p, int l, int r)
28 {
29     if(l < r)
30     {
31         int mid = (l + r) >> 1;
32         build(p<<1, l, mid);
33         build(p<<1|1, mid + 1, r);
34         gather(p);
35     }
36     else{
37         T[p] = vector<LL>(61, 0);
38         if (a[l] == 0) return;
39         for (int j = 0; j <= 60; ++j)
40             if ((1LL << j) & a[l]) {
41                 T[p][j] = a[l];
42                 break;
43             }
44     }
45 }
46 vector<LL>query(int p, int tl, int tr, int l, int r)
47 {
48     if(tl > tr) return vector<LL>(61, 0);
49     if(tr < l || r < tl) return vector<LL>(61, 0);
50     if(l <= tl && tr <= r) return T[p];
51     int mid = (tl + tr) >> 1;
52     return Union(query(p<<1, tl, mid, l, r), query(p<<1|1, mid+1, tr, l, r));
53 }
54 
55 int main(){
56     int N, M;
57     scanf("%d %d", &N, &M);
58     assert(1 <= N && N <= 50000 && M >= 0 && M <= 10000);
59     for(int i = 1; i <= N; ++i) scanf("%lld", a + i), assert(a[i] <= (1LL << 60));
60     build(1, 1, N);
61     while(M--){
62         int L, R, T;
63         scanf("%d %d %d", &L, &R, &T);
64         assert(1 <= L && L <= R && R <= N && T >= 0 && T <= 60);
65         S = vector<LL>(61, 0);
66         for(int i = 1; i <= T; ++i){
67             LL x;
68             scanf("%lld", &x);
69             assert(x <= (1LL << 60));
70             for(int j = 0; j <= 60; ++j) {
71                 if ((x & (1LL << j)) == 0) continue;
72                 if (!S[j]) {
73                     S[j] = x;
74                     break;
75                 }
76                 else x ^= S[j];
77             }
78         }
79         vector<LL> tmp = Union(S, query(1, 1, N, L, R));
80         LL ans = 0;
81         for(int j = 0; j <= 60; ++j){
82             if(tmp[j] && !S[j]) ans++;
83         }
84         printf("%lld
", (1LL << ans));
85     }
86     return 0;
87 }
Aguin
原文地址:https://www.cnblogs.com/Aguin/p/8907548.html