首页 > 其他分享 >20241115

20241115

时间:2024-11-17 12:40:05浏览次数:1  
标签:ld lb int 1000005 20241115 include dp

T1

自闭

题目条件可以扩展到任意矩形的四个顶点。则整个矩阵仅由第一行和第一列决定。容易发现最左上角的格子直接填 \(0\) 是一定合法的,因此只需要判断是否存在数组 \(a_i, b_i\) 满足 \(A_{i, j} = a_i + b_j\) 即可。考虑将给出的限制视为边,\(a_i, b_j\) 视为点建图,显然不同连通块之间没有任何关系。对于每个连通块,只需要任选一个点令其值为 \(0\),然后求出这个连通块中所有点的取值,然后只需要这个连通块中的 \(\min a_i + \min b_j \ge 0\),这个连通块就合法。当且仅当所有连通块都合法,原图合法。使用 bfs,复杂度线性。

代码
#include <iostream>
#include <string.h>
#include <queue>
using namespace std;
int n, m, K;
int head[200005], nxt[400005], to[400005], ew[400005], ecnt;
void add(int u, int v, int ww) { to[++ecnt] = v, nxt[ecnt] = head[u], head[u] = ecnt, ew[ecnt] = ww; }
int dist[200005];
bool vis[200005];
queue<int> q;
int main() {
    freopen("zibi.in", "r", stdin);
    freopen("zibi.out", "w", stdout);
    cin >> n >> m >> K;
    for (int i = 1; i <= K; i++) {
        int x, y, w;
        cin >> x >> y >> w;
        add(x, y + n, w);
        add(y + n, x, w);
    }
    for (int i = 1; i <= n; i++) {
        if (vis[i]) 
            continue;
        q.push(i);
        vis[i] = 1;
        int amn = 0, bmn = 2147483647;
        while (!q.empty()) {
            int x = q.front();
            q.pop();
            for (int i = head[x]; i; i = nxt[i]) {
                int v = to[i];
                if (!vis[v]) {
                    vis[v] = 1;
                    dist[v] = ew[i] - dist[x];
                    q.push(v);
                    if (v <= n) 
                        amn = min(amn, dist[v]);
                    else 
                        bmn = min(bmn, dist[v]);
                } else if (dist[v] != ew[i] - dist[x]) {
                    cout << "Zikai\n";
                    return 0;
                }
            }
            if (bmn + amn < 0) {
                cout << "Zikai\n";
                return 0;
            }
        }
    }
    cout << "Zibi\n";
    return 0;
}

T2

先二分答案,然后考虑 \(dp_i\) 表示用前 \(i\) 条狗最多能覆盖到哪一根骨头。这个 dp 和那个 Lanterns 很像,就是当前狗向前,或当前狗向后,或者当前狗向前且前一条狗向后。分别判断转移条件进行转移即可。

代码
#include <iostream>
#include <string.h>
using namespace std;
int n, dogcount, bone;
string str;
int lb[1000005], rb[1000005];
int ld[1000005], rd[1000005];
int id[1000005];
int dp[1000005], pmx[1000005];
bool chk(int k) {
    int mx = 0;
    memset(dp, 0, sizeof dp);
    memset(pmx, 0, sizeof pmx);
    for (int i = 1; i <= n; i++) {
        if (str[i] != 'D') 
            continue;
        if (mx >= lb[i]) 
            dp[i] = max(dp[i], lb[min(n, i + k)]);
        if (i <= k + 1 || dp[ld[i - 1]] >= lb[i - k - 1]) 
            dp[i] = max(dp[i], lb[i]);  
        if (i >= k + 1) {
            if (ld[i - 1] && ld[i - 1] >= i - k) {
                if (ld[i - 1] == rd[i - k]) {
                    if (dp[ld[i - k - 1]] >= lb[i - k - 1]) 
                        dp[i] = max(dp[i], max(dp[ld[i - 1]], lb[min(n, ld[i - 1] + k)]));
                } else {
                    if (dp[rd[i - k]] >= lb[i - k - 1])
                        dp[i] = max(dp[i], max(dp[ld[i - 1]], lb[min(n, ld[i - 1] + k)]));
                }
            }
        } else if (ld[i - 1])
            dp[i] = max(dp[i], lb[min(n, ld[i - 1] + k)]);
        pmx[i] = max(dp[i], pmx[ld[i - 1]]);
        mx = max(mx, dp[i]);
    }
    return pmx[ld[n]] >= lb[n];
}
int main() {
    freopen("dogs.in", "r", stdin);
    freopen("dogs.out", "w", stdout);
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> str;
    str = ' ' + str;
    for (int i = 1; i <= n + 1; i++) lb[i] = (str[i] == 'B' ? i : lb[i - 1]), ld[i] = (str[i] == 'D' ? i : ld[i - 1]), id[i] = id[i - 1] + (str[i] == 'B');
    rd[n + 1] = rb[n + 1] = n + 1;
    for (int i = n; ~i; i--) rd[i] = (str[i] == 'D' ? (++dogcount, i) : rd[i + 1]), rb[i] = (str[i] == 'B' ? (++bone, i) : rb[i + 1]);
    if (dogcount == 1) {
        int pos = 0;
        for (int i = 1; i <= n; i++) {
            if (str[i] == 'D') 
                pos = i;
        }
        int a = 0, b = pos, c = 0, d = pos;
        for (int i = pos; i; i--) str[i] == 'B' ? (++a, b = i) : 0;
        for (int i = pos; i <= n; i++) str[i] == 'B' ? (++c, d = i) : 0;
        if (a > c) 
            cout << a << " " << pos - b << "\n";
        else if (a < c) 
            cout << c << " " << d - pos << "\n";
        else 
            cout << a << " " << min(pos - b, d - pos) << "\n";
        return 0;
    }
    int l = 1, r = n, mid, ans = -1;
    while (l <= r) {
        mid = (l + r) >> 1;
        if (chk(mid)) 
            ans = mid, r = mid - 1;
        else 
            l = mid + 1;
    }
    cout << bone << " " << ans << "\n";
    return 0;
}

T3

字符串距离

瞎搜,加点剪枝就行了。退火也行。为了提高爆搜正确性,可以考虑对每一个位置先填这一位上的众数,然后按照出现次数枚举填其他字符,再按照众数出现次数从大往小填每一位。这样搜加卡时即可通过。

代码
#include <iostream>
#include <algorithm>
#include <time.h>
using namespace std;
int n, m, d, mx;
string str[1005];
string cur = " ";
int dist[1005];
int cnt[20005][30];
int p[20005][30], q[20005];
void dfs(int y) {
    if (1.0 * clock() / CLOCKS_PER_SEC >= 0.95) {
        cout << "-1\n";
        exit(0);
    }
    if (y == m + 1) {
        cout << cur.substr(1) << "\n";
        exit(0);
    }
    int x = q[y];
    // cout << y << " " << x << " a\n";
    for (int _ = 0; _ < 26; _++) {
        if (cnt[x][p[x][_]] == n) 
            continue;
        int i = p[x][_];
        // cout << _ << " " << i << " b\n";
        bool ok = 1;
        for (int j = 1; j <= n; j++) {
            if (dist[j] + (i != str[j][x] - 'a') > d) {
                ok = 0;
                break;
            }
        }
        if (ok) {
            for (int j = 1; j <= n; j++) dist[j] += (i != str[j][x] - 'a');
            cur[x] = i + 'a';
            dfs(y + 1);
            for (int j = 1; j <= n; j++) dist[j] -= (i != str[j][x] - 'a');
        }
    }
}
int main() {
    freopen("string.in", "r", stdin);
    freopen("string.out", "w", stdout);
    cin >> n >> m >> d;
    for (int i = 1; i <= m; i++) {
        cur += ' ', q[i] = i;
        for (int j = 0; j < 26; j++) cnt[i][j] = n;
    }
    for (int i = 1; i <= n; i++) {
        cin >> str[i];
        str[i] = ' ' + str[i];
        for (int j = 1; j <= m; j++) --cnt[j][str[i][j] - 'a'];
    }
    for (int i = 1; i <= m; i++) {
        for (int j = 0; j < 26; j++) p[i][j] = j;
        sort(p[i], p[i] + 26, [i](int a, int b) { return cnt[i][a] < cnt[i][b]; });
    }
    sort(q + 1, q + m + 1, [](int a, int b) { return cnt[a][p[a][0]] < cnt[b][p[b][0]]; });
    dfs(1);
    cout << "-1\n";
    return 0;
}

T4

独立集

莫名其妙的构造题。先把所有边从小的指向大的,只需要对每个点 \(x\) 找出一个集合 \(S(x)\),使得 存在一条从没有入度的点走到 \(x\) 的路径的长度模 \(k\) 余 \(i \iff i \in S(x)\),然后找到一个 \(c\) 使得 \(c \in S(x) \land (c \bmod k + 1) \notin S(x)\),然后把 \(x\) 染成颜色 \(c \bmod k + 1\) 即可。可以发现这是对的。

代码
#include <iostream>
#include <vector>
using namespace std;
int n, m, k;
int clr[1000005], cnt[1000005];
vector<int> vec[1000005];
int main() {
    freopen("set.in", "r", stdin);
    freopen("set.out", "w", stdout);
    cin >> n;
    cin >> n >> m >> k;
    for (int i = 1; i <= m; i++) {
        int u, v;
        cin >> u >> v;
        vec[max(u, v)].emplace_back(min(u, v));
    }
    for (int i = 1; i <= n; i++) {
        if (vec[i].empty()) 
            clr[i] = 1;
        else {
            for (int v : vec[i]) cnt[clr[v]]++;
            for (int v : vec[i]) {
                if (!cnt[clr[v] % k + 1]) {
                    clr[i] = clr[v] % k + 1;
                    break;
                }
            }
            for (int v : vec[i]) cnt[clr[v]]--;
        }
    }
    for (int i = 1; i <= n; i++) cout << clr[i] << " ";
    cout << "\n";
    return 0;
}

标签:ld,lb,int,1000005,20241115,include,dp
From: https://www.cnblogs.com/forgotmyhandle/p/18550391

相关文章

  • [鲜花] 20241115 My(self+life).
    它是我的生命。我透过明亮的镜子看过去,是我与我的生命的像,还有它的影子,还有那些...意料之外,情理之中。或许我早就感知到它的存在,生活中总是能感觉到它的温度:触碰到了它的体感肌肤,传递冷暖于我。我想找到它,或者说:我想找到属于我自己的东西。可在我轻微的挪动之后,它彻底不见了。从......
  • 20241115
    Talesofseafaring发现需要维护最短路为单数和双数的最短路,所以先跑个最短路,然后对于每个询问看d是单数还是双数,然后判断输出就行,注意到直接这么写然后对于每个询问再查的话空间会爆,所以就把询问记录下来对于每个点为起始跑最短路的时候直接更新答案就行。公路修建问题求最大......
  • 深入理解 MySQL 大小写敏感性:配置、问题与实践指南20241115
    深入理解MySQL大小写敏感性:配置、问题与实践指南在开发和部署MySQL数据库时,表名的大小写敏感性问题常常被忽略,却可能在跨平台迁移、团队协作或工具兼容性方面引发复杂的故障。本文将结合实际案例,深入探讨MySQL的lower_case_table_names参数,剖析其行为、配置方法以......