zoukankan      html  css  js  c++  java
  • 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
    ", 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
    ", 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
    %lld
    ", dis[ed] - 1, cnt[ed]);
    91     }
    92     return 0;
    93 }
    C
  • 相关阅读:
    python并发编程之深入理解yield from
    python中的多进程编程
    Python并发concurrent、Future类、异步
    【Socket通信】关于Socket通信原理解析及python实现
    深入理解Python元类
    Django RestFrameWork 源码解析
    Django的Restful规范
    小程序colorUI框架初步使用教程
    类似按键精灵的鼠标键盘录制和自动化操作 模拟点击和键入 (KeyMouseGo)
    如何在postgresql中,一句sql完成未有数据记录的insert,再update的操作
  • 原文地址:https://www.cnblogs.com/gekoo/p/11348773.html
Copyright © 2011-2022 走看看