牛客小白月赛4

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

 

posted @ 2018-06-16 23:21  Aguin  阅读(394)  评论(0编辑  收藏  举报