NOIP模拟测试19

数据好水,暴力干翻正解(((

Problem A: count

一个能被分成大小为k的联通块,必定满足k | n。预处理每个子树大小,枚举n的因子。

我本来以为是树形DP,但颓不出来柿子Orz,把暴力交了结果A了。。

这个做法很容易被卡到T飞:一个长度有巨多因子的链就可以做到。但数据真的很水。。。。

 

 1 #include <bits/stdc++.h>
 2 
 3 const int N = 20000005;
 4 int n, ans, ecnt;
 5 int siz[N], head[N];
 6 struct Edge {int to, nxt;} e[N << 1];
 7 
 8 inline int read() {
 9     int a = 0; char c = getchar();
10     while (!isdigit(c)) c = getchar();
11     while (isdigit(c)) a = a * 10 + c - '0', c = getchar();
12     return a;
13 }
14 
15 inline void addEdge(int f, int to) {
16     e[++ecnt] = {to, head[f]}, head[f] = ecnt;
17     e[++ecnt] = {f, head[to]}, head[to] = ecnt;
18 }
19 
20 void dfs(int x, int fa) {
21     siz[x] = 1;
22     for (int i = head[x], y = e[i].to; i; i = e[i].nxt, y = e[i].to) {
23         if (y != fa) {
24             dfs(y, x);
25             siz[x] += siz[y];
26         }
27     }
28 }
29 
30 signed main() {
31     n = read();
32     for (int i = 1; i < n; i++) {
33         int x = read(), y = read();
34         addEdge(x, y);
35     }
36     dfs(1, 0);
37     for (int i = 1; i <= n; i++) {
38         if (n % i == 0) {
39             int tmp = 0;
40             for (int j = 1; j <= n; j++) {
41                 if (siz[j] % i == 0) tmp++;
42             }
43             if (tmp == n / i) ans++;
44         }
45     }
46     return !printf("%d\n", ans);
47 }
A

 

Problem B: dinner

破环为链,找出这条链上长度为n的一段

裸暴力是N^3的,考虑优化,我写了二分套二分,加一点比较tricky的小剪枝。

正确性其实我是不敢确定的,因为我也没证。但WA了总比T了好(逃

 

 1 #include <bits/stdc++.h>
 2 
 3 int n, m, mx, sum;
 4 int t[100005], pre[100005];
 5 
 6 inline int read() {
 7     int a = 0; char c = getchar();
 8     while (!isdigit(c)) c = getchar();
 9     while (isdigit(c)) a = a * 10 + c - '0', c = getchar();
10     return a;
11 }
12 
13 bool check(int x) {
14     for (int i = n + 1, tot = 0; i >= 1 && tot + t[i] <= x; tot += t[i--]){
15         int p = i - 1, div = 0;
16         while (p < i + n - 1) {
17             int l = p + 1, r = i + n - 1, mid, ans;
18             while (l <= r) {
19                 mid = (l + r) >> 1;
20                 if (pre[mid] - pre[p] <= x)
21                     ans = mid, l = mid + 1;
22                 else r = mid - 1;
23             }
24             p = ans;
25             ++div;
26             if (div > m) break;
27         }
28         if (p == i + n - 1 && div <= m) return true;
29     }
30     return false;
31 }
32 
33 signed main() {
34     n = read(), m = read();
35     for (int i = 1; i <= n; i++) {
36         t[i] = read(), t[i + n] = t[i];
37         sum += t[i];
38         mx = std::max(mx, t[i]);
39     }
40     for (int i = 1; i <= 2 * n; i++)
41         pre[i] = pre[i - 1] + t[i];
42     int l = mx, r = sum, mid, ans = 0;
43     while (l <= r) {
44         mid = (l + r) >> 1;
45         if (check(mid)) r = mid - 1, ans = mid;
46         else l = mid + 1;
47     }
48     return !printf("%d\n", ans);
49 }
B

 

Problem C: chess

考场5min敲了个DFS骗10分,性价比真高啊(

正解:建图跑最短路计数。

但题目中有个条件:两条路径只有经过的空格有不一样才能被认为是不同的。

于是就出现零环的问题,它没用。

怎么解决?我们扫一遍图,对于权值为1的点dfs一遍去连边,这样可以避免零环,连出有效的边。

这题数据锅了,这个做法当时只有70pt。。。换数据后就能A了XD

 

 1 #include <bits/stdc++.h>
 2 #define id(x, y) ((x - 1) * m + y)
 3 
 4 const int N = 300003;
 5 const int dx[8] = {-2, -2, -1, -1, 1, 1, 2, 2};
 6 const int dy[8] = {-1, 1, -2, 2, -2, 2, -1, 1};
 7 int n, m, st, ed;
 8 long long dis[N], cnt[N];
 9 int matrix[505][505], mp[2505][2505];
10 bool vis[N];
11 std::vector<int> v;
12 
13 inline int read() {
14     int a = 0; char c = getchar();
15     while (!isdigit(c)) c = getchar();
16     while (isdigit(c)) a = a * 10 + c - '0', c = getchar();
17     return a;
18 }
19 
20 void dfs(int x, int y) {
21     vis[id(x, y)] = 1;
22     for (int i = 0; i <= 7; i++) {
23         int xx = x + dx[i], yy = y + dy[i];
24         if (xx < 1 || yy < 1 || xx > n || yy > n || vis[id(xx, yy)]) continue;
25         if (matrix[xx][yy] != 1 && matrix[xx][yy] != 2) {
26             v.push_back(id(xx, yy));
27             vis[id(xx, yy)] = 1;
28         } else if (matrix[xx][yy] == 1) dfs(xx, yy);
29     }
30 }
31 
32 void bfs() {
33     memset(dis, 0x3f, sizeof(dis));
34     dis[st] = 0, cnt[st] = 1;
35     std::queue<int> q;
36     q.push(st);
37     while (!q.empty()) {
38         int x = q.front();
39         q.pop();
40         for (int i = 1; i <= n * m; i++) {
41             if (mp[x][i]) {
42                 if (dis[i] > dis[x] + 1) {
43                     if (dis[i] == 0x3f3f3f3f3f3f3f3f) q.push(i);
44                     dis[i] = dis[x] + 1;
45                     cnt[i] = cnt[x];
46                 } else if (dis[i] == dis[x] + 1) cnt[i] += cnt[x];
47             }
48         }
49     }
50 }
51 
52 signed main() {
53     n = read(), m = read();
54     for (int i = 1; i <= n; i++) {
55         for (int j = 1; j <= m; j++) {
56             matrix[i][j] = read();
57             if (matrix[i][j] == 3) st = id(i, j);
58             if (matrix[i][j] == 4) ed = id(i, j);
59         }
60     }
61     for (int i = 1; i <= n; i++) {
62         for (int j = 1; j <= m; j++) {
63             if (matrix[i][j] == 1 && !vis[id(i, j)]) {
64                 dfs(i, j);
65                 for (int x = 0; x < v.size(); x++) {
66                     for (int y = x + 1; y < v.size(); y++) {
67                         mp[v[x]][v[y]] = mp[v[y]][v[x]] = 1;
68                     }
69                 }
70                 for (auto x : v) vis[x] = 0;
71                 v.clear();
72             }
73         }
74     }
75     for (int i = 1; i <= n; i++) {
76         for (int j = 1; j <= m; j++) {
77             if (matrix[i][j] == 1 || matrix[i][j] == 2) continue;
78             for (int k = 0; k <= 7; k++) {
79                 int x = i + dx[k], y = j + dy[k];
80                 if (x < 1 || y < 1 || x > n || y > m) continue;
81                 if (matrix[x][y] == 2 || matrix[x][y] == 1) continue;
82                 mp[id(i, j)][id(x, y)] = mp[id(x, y)][id(i, j)] = 1;
83             }
84         }
85     }
86     bfs();
87     if (dis[ed] == 0x3f3f3f3f3f3f3f3f) {
88         puts("-1");
89     } else {
90         printf("%lld\n%lld\n", dis[ed] - 1, cnt[ed]);
91     }
92     return 0;
93 }
C

 

posted @ 2019-08-14 19:37  Gekoo  阅读(187)  评论(0编辑  收藏  举报