1. 程式人生 > >牛客小白月賽4

牛客小白月賽4

sort 暴力 n) b16 黑白 不能 close pla 浮點數

A.三角形

經典暴力:由於不能構成三角形邊長至少乘二,只用考慮最大的log個暴力

技術分享圖片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 1e5 + 10;
 4 typedef long long LL;
 5 LL a[maxn], id[maxn], vis[maxn], ans[maxn];
 6  
 7 bool cmp(LL i, LL j) {
 8     return a[i] > a[j];
 9 }
10  
11 int main() {
12     int n, q;
13 scanf("%d %d", &n, &q); 14 for(int i = 1; i <= n; ++i) scanf("%lld", a + i), id[i] = i; 15 sort(id + 1, id + 1 + n, cmp); 16 LL M = -1; 17 for(int i = 1; i <= min(35, n); ++i) { 18 vis[id[i]] = 1; 19 for(int j = i + 1; j <= min(35, n); ++j) { 20
for(int k = j + 1; k <= min(35, n); ++k) { 21 LL I = id[i], J = id[j], K = id[k]; 22 if(a[I] + a[J] > a[K] && a[J] + a[K] > a[I] && a[I] + a[K] > a[J]) 23 M = max(M, a[I] + a[J] + a[K]); 24 } 25 }
26 } 27 for(int o = 1; o <= n; ++o) { 28 if(!vis[o]) ans[o] = M; 29 else { 30 LL MM = -1; 31 for(int i = 1; i <= min(35, n); ++i) { 32 if(id[i] == o) continue; 33 for(int j = i + 1; j <= min(35, n); ++j) { 34 if(id[j] == o) continue; 35 for(int k = j + 1; k <= min(35, n); ++k) { 36 if(id[k] == o) continue; 37 LL I = id[i], J = id[j], K = id[k]; 38 if(a[I] + a[J] > a[K] && a[J] + a[K] > a[I] && a[I] + a[K] > a[J]) 39 MM = max(MM, a[I] + a[J] + a[K]); 40 } 41 } 42 } 43 ans[o] = MM; 44 } 45 } 46 while(q--) { 47 int x; 48 scanf("%d", &x); 49 printf("%lld\n", ans[x]); 50 } 51 return 0; 52 }
Aguin

B.博弈論

三位數不到1000個,直接暴力

技術分享圖片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int a[1111];
 4 set<int> S;
 5  
 6 int main() {
 7     int n;
 8     scanf("%d", &n);
 9     for(int i = 1; i <= n; ++i) scanf("%d", a + i);
10     for(int l = 1; l <= 4; ++l) {
11         for(int st = 1; st + l - 1 <= n; ++st) {
12             int t = 0;
13             for(int i = st; i <= st + l - 1; ++i) t = t * 10 + a[i];
14             S.insert(t);
15         }
16     }
17     for(int i = 0; ; ++i) {
18         if(S.find(i) == S.end()) {
19             printf("%d\n", i);
20             break;
21         }
22     }
23     return 0;
24 }
Aguin

C.病菌感染

BFS

技術分享圖片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int n, cnt[1111][1111], vis[1111][1111];
 4 int dx[] = {0, 1, 0, -1};
 5 int dy[] = {-1, 0, 1, 0};
 6  
 7 typedef pair<int, int> pii;
 8  
 9  
10 bool in(int i, int j) {
11     return i >= 1 && i <= n && j >= 1 && j <= n;
12 }
13  
14 int main() {
15     int m;
16     scanf("%d %d", &n, &m);
17     int tot = m;
18     queue<pii> q;
19     for(int i = 1; i <= m; ++i) {
20         int x, y;
21         scanf("%d %d", &x, &y);
22         q.push(pii(x, y));
23         vis[x][y] = 1;
24     }
25     while(!q.empty()) {
26         pii tmp = q.front(); q.pop();
27         int x = tmp.first, y = tmp.second;
28         for(int d = 0; d < 4; ++d) {
29             int nx = x + dx[d], ny = y + dy[d];
30             if(!in(nx, ny)) continue;
31             if(vis[nx][ny]) continue;
32             cnt[nx][ny]++;
33             if(cnt[nx][ny] >= 2) {
34                 q.push(pii(nx, ny));
35                 tot++;
36                 vis[nx][ny] = 1;
37             }
38         }
39     }
40     puts(tot == n * n ? "YES" : "NO");
41     return 0;
42 }
Aguin

D.郊區春遊

題意感人害我中獎,Floyd狀壓

技術分享圖片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int G[222][222], id[22], f[1<<15][16];
 4 const int INF = 1e9;
 5  
 6 int main() {
 7     int n, m, R;
 8     scanf("%d %d %d", &n, &m, &R);
 9     for(int i = 1; i <= R; ++i) scanf("%d", id + i);
10     for(int i = 1; i <= n; ++i)
11         for(int j = i + 1; j <= n; ++j)
12                 G[i][j] = G[j][i] = INF;
13     for(int i = 1; i <= m; ++i) {
14         int A, B, C;
15         scanf("%d %d %d", &A, &B, &C);
16         G[A][B] = G[B][A] = C;
17     }
18     for(int k = 1; k <= n; ++k)
19         for(int i = 1; i <= n; ++i)
20             for(int j = 1; j <= n; ++j)
21                 G[i][j] = min(G[i][j], G[i][k] + G[k][j]);
22     for(int i = 0; i < (1 << R); ++i)
23         for(int j = 1; j <= R; ++j)
24             f[i][j] = INF;
25     for(int i = 1; i <= R; ++i) f[1<<(i - 1)][i] = 0;
26     for(int i = 0; i < (1 << R); ++i){
27         for(int j = 1; j <= R; ++j) {
28             if(f[i][j] == INF) continue;
29             for(int k = 1; k <= R; ++k) {
30                 if(i & (1 << (k - 1))) continue;
31                 f[i ^ (1 << (k - 1))][k] = min(f[i ^ (1 << (k - 1))][k], f[i][j] + G[id[j]][id[k]]);
32             }
33         }
34     }
35     int ans = INF;
36     for(int i = 1; i <= R; ++i) ans = min(ans, f[(1<<R)-1][i]);
37     printf("%d\n", ans);
38     return 0;
39 }
Aguin

E.浮點數輸出

直接字符串

技術分享圖片
1 #include <bits/stdc++.h>
2 using namespace std;
3 char s[1111111];
4  
5 int main() {
6     cin >> s;
7     cout << s << endl;
8     return 0;
9 }
Aguin

F.等價串

把操作2看成對B串增加111或者000,最後只要判一下模3余數

技術分享圖片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 char a[111], b[111];
 4  
 5 int main() {
 6     int T;
 7     scanf("%d", &T);
 8     while(T--) {
 9         int n, m, x = 0, y = 0;
10         scanf("%d %d %s %s", &n, &m, a + 1, b + 1);
11         for(int i = 1; i <= n; ++i)
12             if(a[i] == 0) y = (y + 1) % 3;
13             else y = (y + 2) % 3;
14         for(int i = 1; i <= m; ++i) {
15             if(b[i] - 0 != x) x ^= 1, y = y * 2 % 3;
16             y = (y + 2) % 3;
17         }
18         puts(y ? "NO" : "YES");
19     }
20     return 0;
21 }
Aguin

G.黑白棋

很好寫的模擬?

技術分享圖片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int dx[] = {-1, 0, 1, -1, 1, -1, 0, 1};
 4 int dy[] = {-1, -1, -1, 0, 0, 1, 1, 1};
 5 int G[11][11];
 6  
 7 int flip(int x, int y, int o) {
 8     int ret = 0;
 9     for(int d = 0; d < 8; ++d) {
10         int nx = x + dx[d], ny = y + dy[d];
11         if(G[nx][ny] != 1 - o) continue;
12         for(int xx = nx + dx[d], yy = ny + dy[d]; ; xx += dx[d], yy += dy[d]) {
13             if(G[xx][yy] == -1) break;
14             if(G[xx][yy] == o) {
15                 for(int tx = nx, ty = ny; tx != xx || ty != yy; tx += dx[d], ty += dy[d]) {
16                     G[tx][ty] ^= 1;
17                     ret++;
18                 }
19                 break;
20             }
21         }
22     }
23     return ret;
24 }
25  
26 int main() {
27     memset(G, -1, sizeof(G));
28     G[4][5] = G[5][4] = 1;
29     G[4][4] = G[5][5] = 0;
30     int x, y, o = 1;
31     while(~scanf("%d %d", &x, &y)) {
32         if(!flip(x, y, o)) flip(x, y, o ^ 1), G[x][y] = o ^ 1;
33         else G[x][y] = o, o ^= 1;
34     }
35     int w = 0, b = 0;
36     for(int i = 1; i <= 8; ++i)
37         for(int j = 1; j <= 8; ++j)
38             if(G[i][j] == 1) b++;
39             else if(G[i][j] == 0) w++;
40     printf("%d:%d\n", b, w);
41     return 0;
42 }
Aguin

H.相鄰的糖果

貪心從後往前吃,可以用一個棧維護沒吃完的

技術分享圖片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int maxn = 1e6 + 10;
 5 stack<int> st;
 6 LL a[maxn];
 7  
 8 int main() {
 9     int n, m, x;
10     scanf("%d %d %d", &n, &m, &x);
11     for(int i = 1; i <= n; ++i) scanf("%lld", a + i);
12     LL sum = 0, ans = 0;
13     for(int i = 1; i < m; ++i) st.push(i), sum += a[i];
14     for(int i = m; i <= n; ++i) {
15         sum -= a[i-m];
16         sum += a[i];
17         st.push(i);
18         while(sum > x) {
19             int id = st.top();
20             LL y = min(sum - x, a[id]);
21             a[id] -= y;
22             sum -= y;
23             ans += y;
24             if(a[id] == 0) st.pop();
25         }
26     }
27     printf("%lld\n", ans);
28     return 0;
29 }
Aguin

I.合唱隊形

枚舉一下連接點

技術分享圖片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 1e5 + 10;
 4 int L[maxn], R[maxn];
 5 char s[maxn];
 6  
 7 int main() {
 8     int n, tot = 0;
 9     scanf("%d %s", &n, s + 1);
10     for(int i = 1; i <= n; ++i) {
11         if(s[i] == 0) L[i] = L[i-1] + 1, tot++;
12         else L[i] = 0;
13     }
14     for(int i = n; i >= 1; --i) {
15         if(s[i] == 0) R[i] = R[i+1] + 1;
16         else R[i] = 0;
17     }
18     int ans = 0;
19     for(int i = 1; i <= n; ++i) {
20         if(L[i] == tot) ans = tot;
21         else ans = max(ans, L[i] + 1);
22     }
23     for(int i = 2; i < n; ++i) {
24         int x = L[i-1] + R[i+1];
25         if(x != tot) ans = max(ans, x + 1);
26     }
27     printf("%d\n", ans);
28     return 0;
29 }
Aguin

J.強迫癥

每次把目前最大的數加到一個重復的數上

技術分享圖片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 set<int> S;
 4  
 5 int main() {
 6     int n, x, ans = 0;
 7     scanf("%d", &n);
 8     for(int i = 1; i <= n; ++i) {
 9         scanf("%d", &x);
10         if(S.find(x) != S.end()) ans++;
11         S.insert(x);
12     }
13     printf("%d\n", ans);
14     return 0;
15 }
Aguin

牛客小白月賽4