SenseTime Ace Coder Challenge 暨 商汤在线编程挑战赛*

A.双人取数

预处理四个角,枚举重叠段,发现可以前缀max

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 const int INF = 1e9;
  4 int G[1111][1111], lu[1111][1111], ru[1111][1111], ld[1111][1111], rd[1111][1111];
  5 
  6 int main(){
  7     int T;
  8     scanf("%d", &T);
  9     for(int kase = 1; kase <= T; kase++){
 10         int n, m;
 11         scanf("%d %d", &n, &m);
 12         for(int i = 1; i <= n; ++i)
 13             for(int j = 1; j <= m; ++j)
 14                 scanf("%d", &G[i][j]);
 15         // lu
 16         lu[1][1] = G[1][1];
 17         for(int i = 1; i <= n; ++i){
 18             for(int j = 1; j <= m; ++j){
 19                 if(i == 1 && j == 1) continue;
 20                 if(i == 1) lu[i][j] = lu[i][j-1] + G[i][j];
 21                 else if(j == 1) lu[i][j] = lu[i-1][j] + G[i][j];
 22                 else lu[i][j] = max(lu[i-1][j], lu[i][j-1]) + G[i][j];
 23             }
 24         }
 25         // ru
 26         ru[1][m] = G[1][m];
 27         for(int i = 1; i <= n; ++i){
 28             for(int j = m; j >= 1; --j){
 29                 if(i == 1 && j == m) continue;
 30                 if(i == 1) ru[i][j] = ru[i][j+1] + G[i][j];
 31                 else if(j == m) ru[i][j] = ru[i-1][j] + G[i][j];
 32                 else ru[i][j] = max(ru[i-1][j], ru[i][j+1]) + G[i][j];
 33             }
 34         }
 35         // ld
 36         ld[n][1] = G[n][1];
 37         for(int i = n; i >= 1; --i){
 38             for(int j = 1; j <= m; ++j){
 39                 if(i == n && j == 1) continue;
 40                 if(i == n) ld[i][j] = ld[i][j-1] + G[i][j];
 41                 else if(j == 1) ld[i][j] = ld[i+1][j] + G[i][j];
 42                 else ld[i][j] = max(ld[i+1][j], ld[i][j-1]) + G[i][j];
 43             }
 44         }
 45         // rd
 46         rd[n][m] = G[n][m];
 47         for(int i = n; i >= 1; --i){
 48             for(int j = m; j >= 1; --j){
 49                 if(i == n && j == m) continue;
 50                 if(i == n) rd[i][j] = rd[i][j+1] + G[i][j];
 51                 else if(j == m) rd[i][j] = rd[i+1][j] + G[i][j];
 52                 else rd[i][j] = max(rd[i+1][j], rd[i][j+1]) + G[i][j];
 53             }
 54         }
 55 
 56         int ans = -INF;
 57         for(int i = 1; i <= n; ++i){
 58             int sum = 0, M = -INF;
 59             for(int j = 1; j <= m; ++j){
 60                 int t1, t2;
 61                 if(i == 1 && j == 1) t1 = ld[i+1][j];
 62                 else if(i == n && j == 1) t1 = lu[i-1][j];
 63                 else if(i == 1) t1 = lu[i][j-1] + ld[i+1][j];
 64                 else if(i == n) t1 = lu[i-1][j] + ld[i][j-1];
 65                 else if(j == 1) t1 = lu[i-1][j] + ld[i+1][j];
 66                 else t1 = max(lu[i-1][j] + ld[i+1][j], max(lu[i-1][j] + ld[i][j-1], lu[i][j-1] + ld[i+1][j]));
 67                 if(i == 1 && j == m) t2 = rd[i+1][j];
 68                 else if(i == n && j == m) t2 = ru[i-1][j];
 69                 else if(i == 1) t2 = ru[i][j+1] + rd[i+1][j];
 70                 else if(i == n) t2 = ru[i-1][j] + rd[i][j+1];
 71                 else if(j == m) t2 = ru[i-1][j] + rd[i+1][j];
 72                 else t2 = max(ru[i-1][j] + rd[i+1][j], max(ru[i-1][j] + rd[i][j+1], ru[i][j+1] + rd[i+1][j]));
 73                 ans = max(ans, sum + G[i][j] + t2 + M);
 74                 M = max(M, t1 - sum);
 75                 sum += G[i][j];
 76             }
 77         }
 78         for(int j = 1; j <= m; ++j){
 79             int sum = 0, M = -INF;
 80             for(int i = 1; i <= n; ++i){
 81                 int t1, t2;
 82                 if(i == 1 && j == 1) t1 = ru[i][j+1];
 83                 else if(i == 1 && j == m) t1 = lu[i][j-1];
 84                 else if(j == 1) t1 = lu[i-1][j] + ru[i][j+1];
 85                 else if(j == m) t1 = lu[i][j-1] + ru[i-1][j];
 86                 else if(i == 1) t1 = lu[i][j-1] + ru[i][j+1];
 87                 else t1 = max(lu[i][j-1] + ru[i][j+1], max(lu[i][j-1] + ru[i-1][j], lu[i-1][j] + ru[i][j+1]));
 88                 if(i == n && j == 1) t2 = rd[i][j+1];
 89                 else if(i == n && j == m) t2 = ld[i][j-1];
 90                 else if(j == 1) t2 = ld[i+1][j] + rd[i][j+1];
 91                 else if(j == m) t2 = ld[i][j-1] + rd[i+1][j];
 92                 else if(i == n) t2 = ld[i][j-1] + rd[i][j+1];
 93                 else t2 = max(ld[i][j-1] + rd[i][j+1], max(ld[i][j-1] + rd[i+1][j], ld[i+1][j] + rd[i][j+1]));
 94                 ans = max(ans, sum + G[i][j] + t2 + M);
 95                 M = max(M, t1 - sum);
 96                 sum += G[i][j];
 97             }
 98         }
 99         for(int i = 2; i < n; i++)
100             for(int j = 2; j < m; ++j)
101                 ans = max(ans, G[i][j] + max(lu[i-1][j] + rd[i+1][j] + ru[i][j+1] + ld[i][j-1], lu[i][j-1] + rd[i][j+1] + ru[i-1][j] + ld[i+1][j]));
102         printf("Case #%d: %d
", kase, ans);
103     }
104     return 0;
105 }
Aguin

B.我觉得海星

我bitset过不了冷静分析了一个n3做法

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int G1[222][222], G2[222][222];
 4 
 5 int main(){
 6     int T;
 7     scanf("%d", &T);
 8     for(int kase = 1; kase <= T; ++kase){
 9         int N;
10         scanf("%d", &N);
11         for(int i = 1; i <= N; ++i){
12             char s[222];
13             scanf("%s", s + 1);
14             for(int j = 1; j <= N; ++j)
15                 G1[i][j] = (s[j] == '1' ? 1 : 0), G2[i][j] = 0;
16         }
17         for(int i = 1; i <= N; ++i){
18             for(int j = 1; j <= N; ++j){
19                 if(!G1[i][j]) continue;
20                 for(int k = 1; k <= N; ++k) G2[i][k] += G1[j][k];
21             }
22         }
23         int ans = 0;
24         for(int i = 1; i <= N; ++i){
25             for(int k = 1; k <= N; ++k){
26                 if(i == k) continue;
27                 int c = 0;
28                 for(int p = 1; p <= N; ++p){
29                     if(p == i || p == k) continue;
30                     if(G2[i][p] && G1[k][p]) c++;
31                 }
32                 for(int j = 1; j <= N; ++j){
33                     if(j == i || j == k) continue;
34                     if(!G1[i][j] || !G1[k][j]) continue;
35                     int b = G2[i][j] && G1[k][j] ? 1 : 0;
36                     ans += c - b;
37                 }
38             }
39         }
40         for(int j = 1; j <= N; ++j){
41             for(int p = 1; p <= N; ++p){
42                 if(!G1[j][p]) continue;
43                 int c = 0;
44                 for(int k = 1; k <= N; ++k) c += G1[j][k] && G1[p][k] ? 1 : 0;
45                 for(int i = 1; i <= N; ++i){
46                     if(i == j || i == p) continue;
47                     if(!G1[i][j]) continue;
48                     if(G2[i][p] != 1) continue;
49                     int b = G1[j][i] && G1[p][i] ? 1 : 0;
50                     ans -= c - b + c - b;
51                 }
52             }
53         }
54         for(int i = 1; i <= N; ++i){
55             for(int p = 1; p <= N; ++p){
56                 if(i == p) continue;
57                 if(G2[i][p] != 2) continue;
58                 vector<int> v;
59                 for(int k = 1; k <= N; ++k)
60                     if(G1[i][k] && G1[p][k]) v.push_back(k);
61                 if(G1[v[0]][v[1]]) ans -= 2;
62             }
63         }
64         printf("Case #%d: %s
", kase, ans > 0 ? "Starfish!" : "Walk Walk");
65     }
66     return 0;
67 }
Aguin

C.抽球游戏

FWT开三次根号

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 void FWT_Xor(int *A, int len) {
 5     if (len == 1) return;
 6     int len2 = len >> 1;
 7     FWT_Xor(A, len2);
 8     FWT_Xor(A + len2, len2);
 9     for (int i = 0; i < len2; ++i) {
10         int x = A[i], y = A[i + len2];
11         A[i] = x + y;
12         A[i + len2] = x - y;
13     }
14 }
15 
16 void IFWT_Xor(int *A, int len) {
17     if (len == 1) return;
18     int len2 = len >> 1;
19     for (int i = 0; i < len2; ++i) {
20         int x = A[i], y = A[i + len2];
21         A[i] = (x + y) >> 1;
22         A[i + len2] = (x - y) >> 1;
23     }
24     IFWT_Xor(A, len2);
25     IFWT_Xor(A + len2, len2);
26 }
27 
28 int a[66];
29 int main(){
30     int T;
31     scanf("%d", &T);
32     for(int kase = 1; kase <= T; ++kase){
33         int n, ok = 1, sum = 0;
34         scanf("%d", &n);
35         for(int i = 0; i < 64; ++i) scanf("%d", a + i), sum += a[i];
36         if(sum != n * n * n) ok = 0;
37         FWT_Xor(a, 64);
38         for(int i = 0; i < 64; ++i){
39             int flag = 0;
40             for(int j = 0; j * j * j <= abs(a[i]); ++j)
41                 if(j * j * j == a[i]) {a[i] = j; flag = 1; break;}
42                 else if(j * j * j == -a[i]) {a[i] = -j; flag = 1; break;}
43             if(!flag) ok = 0;
44         }
45         IFWT_Xor(a, 64);
46         vector<int> ans;
47         for(int i = 0; i < 64; ++i)
48             if(a[i] < 0) ok = 0;
49             else for(int j = 0; j < a[i]; ++j)
50                 ans.push_back(i);
51         printf("Case #%d:", kase);
52         if(!ok || ans.size() != n) puts(" -1");
53         else{
54             for(int i = 0; i < ans.size(); ++i) printf(" %d", ans[i]);
55             puts("");
56         }
57     }
58     return 0;
59 }
Aguin

D.最小?最大!

E.反函数求解

我暴力过不了

F.归并排序

G.危险路径

并查集拆边为点

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 6e5 + 10;
 4 typedef long long LL;
 5 typedef pair<LL, LL> pii;
 6 vector<pii> vec;
 7 int u[maxn], v[maxn];
 8 vector<int> G[maxn];
 9 LL tag[maxn], sum[maxn];
10 
11 int fa[maxn];
12 int Find(int x){
13     return fa[x] == x ? x : fa[x] = Find(fa[x]);
14 }
15 void Union(int x, int y){
16     x = Find(x), y = Find(y);
17     if(x == y) return;
18     fa[y] = x;
19 }
20 
21 int n, sz[maxn];
22 void dfs1(int x){
23     sz[x] = x <= n ? 1 : 0;
24     for(int i = 0; i < G[x].size(); ++i) dfs1(G[x][i]), sz[x] += sz[G[x][i]];
25 }
26 void dfs2(int x, LL o){
27     sum[x] = o;
28     for(int i = 0; i < G[x].size(); ++i) dfs2(G[x][i], o + tag[x] * (sz[x] - sz[G[x][i]]));
29 }
30 
31 int main(){
32     int T;
33     scanf("%d", &T);
34     for(int kase = 1; kase <= T; ++kase){
35         int m;
36         scanf("%d %d", &n, &m);
37         int id = n;
38         for(int i = 1; i <= n + n; ++i) fa[i] = i, G[i].clear(), tag[i] = 0;
39         vec.clear();
40         for(int i = 1; i <= m; ++i){
41             LL w;
42             scanf("%d %d %lld", u + i, v + i, &w),
43             vec.push_back(pii(w, i));
44         }
45         sort(vec.begin(), vec.end());
46         for(int i = 0; i < m; ++i){
47             int x = vec[i].second;
48             if(Find(u[x]) == Find(v[x])) continue;
49             LL w = vec[i].first;
50             tag[++id] = w;
51             G[id].push_back(Find(u[x]));
52             G[id].push_back(Find(v[x]));
53             Union(id, Find(u[x]));
54             Union(id, Find(v[x]));
55         }
56         dfs1(id);
57         dfs2(id, 0);
58         LL ans = 0;
59         for(int i = 1; i <= n; ++i) ans ^= sum[i] * i;
60         printf("Case #%d: %lld
", kase, ans);
61     }
62     return 0;
63 }
Aguin
原文地址:https://www.cnblogs.com/Aguin/p/8862342.html