zoukankan      html  css  js  c++  java
  • 省选测试12

    T1看错题,暴力没写对,爆0了,QWQ

    A 灯

    题目大意 : 有m种颜色的灯共n个,每次开启或关上一种颜色的所有,问有几个极长的连续段(注意极长,而不是最长)

    • 对于灯数小于根号的颜色就暴力枚举每个点,对于灯数大于根号的颜色就记录下来,并预处理出这些颜色相互间的影响,而这些颜色种类是不超过根号的,复杂度 (O(nsqrt n))

    Code

    Show Code
    #include <cmath>
    #include <cstdio>
    #include <vector>
    
    using namespace std;
    const int N = 1e5 + 5, M = 330;
    
    int read(int x = 0, int f = 1, char c = getchar()) {
        for (; c < '0' || c > '9'; c = getchar())
            if (c == '-') f = -1;
        for (; c >='0' && c <='9'; c = getchar())
            x = x * 10 + c - '0';
        return x * f;
    }
    
    bool l[N];
    vector<int> v[N];
    int n, m, q, sq, a[N], cnt[N], tot, id[N], f[M][M], ans, s[N], c[N];
    
    int Cal(int x, int op) {
        ans += cnt[x] * op;
        if (id[x]) {
            ans -= s[x] * op;
            for (int i = 1; i <= tot; ++i)
                if (l[c[i]]) ans -= f[id[x]][i] * op;
        }
        else {
            for (int i = 0; i < v[x].size(); ++i) {
                int y = v[x][i];
                ans -= l[a[y-1]] * op; s[a[y-1]] += op;
                ans -= l[a[y+1]] * op; s[a[y+1]] += op;
            }
        }
        return ans;
    }
    
    int main() {
        n = read(); m = read(); q = read();
        for (int i = 1; i <= n; ++i)
            if ((a[i] = read()) == a[i-1]) i--, n--;
        a[n+1] = 0; sq = sqrt(n);
        for (int i = 1; i <= n; ++i) cnt[a[i]]++;
        for (int i = 1; i <= m; ++i)
            if (cnt[i] > sq) c[++tot] = i, id[i] = tot;
        for (int i = 1; i <= n; ++i) {
            if (!id[a[i]]) v[a[i]].push_back(i);
            f[id[a[i-1]]][id[a[i]]]++;
            f[id[a[i]]][id[a[i-1]]]++;
        }
        while (q--) {
            int x = read(); l[x] ^= 1;
            printf("%d
    ", Cal(x, l[x] ? 1 : -1));
        }
        return 0;
    }
    

    B 十字路口

    题目大意 : 给出一个红绿灯系统n个灯在m个时刻的状态,问红绿灯的周期

    • 发现其实就是建图找环

    Code

    Show Code
    #include <cstdio>
    #include <vector>
    #include <cstdlib>
    #include <algorithm>
    
    using namespace std;
    const int N = 1e5 + 5;
    
    int read(int x = 0, int f = 1, char c = getchar()) {
        for (; c < '0' || c > '9'; c = getchar())
            if (c == '-') f = -1;
        for (; c >='0' && c <='9'; c = getchar())
            x = x * 10 + c - '0';
        return x * f;
    }
    
    struct Edge {
        int n, t, d;
    }e[N];
    int h[N], edc;
    
    void Add(int x, int y, int z) {
        e[++edc] = (Edge) {h[x], y, z}; h[x] = edc;
    }
    
    bool v[N], g[N];
    vector<int> f[N];
    int n, m, a[N], i, j, d[N]; 
    
    bool Cmp(int x, int y) {
        return f[i][x] < f[i][y];
    }
    
    void Dfs(int x, int dis) {
        d[x] = dis; v[x] = g[x] = 1;
        for (int i = h[x], y; i; i = e[i].n) {
            if (!v[y=e[i].t]) Dfs(y, dis + e[i].d);
            else if (g[y]) {
                printf("%d
    ", dis + e[i].d - d[y]);
                exit(0);
            }
        }
        g[x] = 0;
    }
    
    int main() {
        m = read(); n = read();
        for (i = 1; i <= n; ++i) {
            f[i].resize(m + 1);
            for (j = 1; j <= m; ++j)
                f[i][j] = read();
        }
        for (i = 1; i <= m; ++i) a[i] = i;
        for (i = 1; i <= n; ++i) {
            sort(a + 1, a + m + 1, Cmp);
            for (j = 2; j <= m; ++j) {
                if (f[i][a[j]] == f[i][a[j-1]]) swap(a[j], a[j-1]);
                else if (f[i][a[j-1]]) Add(a[j-1], a[j], f[i][a[j]] - f[i][a[j-1]]);
            }
        }
        for (i = 1; i <= m; ++i) if (!v[i]) Dfs(i, 0);
        puts("-1");
        return 0;
    }
    

    C 密室逃脱

    题目大意 : 一条通道里,想要通过需要有一定人数的人一直按着按钮,问保证1号点左面通道的门不会打开,通道里最多可以放多少个人

    • 神仙Dp

    Code

    Show Code
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    const int N = 1005;
    
    int read(int x = 0, int f = 1, char c = getchar()) {
        for (; c < '0' || c > '9'; c = getchar())
            if (c == '-') f = -1;
        for (; c >='0' && c <='9'; c = getchar())
            x = x * 10 + c - '0';
        return x * f;
    }
    
    int n, m, a[N], b[N], f[N][N*20], ans;
    //设 f[i][j]表示能到达第 i 个房间的人数恰好为 j 时, 前 i 个房间最多有多少人
    
    int main() {
        n = read(), m = read();
        for (int i = 1; i < n; ++i)
            a[i] = read(), b[i] = read();
        memset(f, 0x8f, sizeof(f));
        for (int i = 0; i < m; ++i) f[1][i] = i;
        for (int i = 1; i < n; ++i) {
            int mx = -2e9;
            for (int j = 0; j < a[i]; ++j) {
                mx = max(mx, f[i][j]);
                f[i+1][j+b[i]] = max(f[i+1][j+b[i]], f[i][j] + b[i]);
            }
            for (int j = 0; j < b[i]; ++j) 
                f[i+1][j] = max(f[i+1][j], mx + j);
            mx = a[i] + b[i];
            for (int j = a[i]; j < mx; ++j)
                f[i+1][j-a[i]] = max(f[i+1][j-a[i]], f[i][j]);
            for (int j = mx; j <= 2e4; ++j)
                f[i+1][j] = max(f[i+1][j], f[i][j]);
        }
        for (int i = 0; i <= 2e4; ++i)
            ans = max(ans, f[n][i]);
        printf("%d
    ", ans);
        return 0;
    }
    
  • 相关阅读:
    div+css清除浮动代码
    JavaScript for循环实现表格隔行变色
    JavaScript 四种显示数据方式
    table表格隔行变色
    table表格用tbody新属性获取DOM元素
    条形图
    子图--面向对象
    线的形状
    matplotlib--直线和点
    颜色和样式字符串
  • 原文地址:https://www.cnblogs.com/shawk/p/14395497.html
Copyright © 2011-2022 走看看