zoukankan      html  css  js  c++  java
  • Codeforces Edu Round 58 A-E

    A. Minimum Integer

    1. 如果(d < l),则(d)满足条件
    2. 否则,输出(d * (r / d + 1))即可。
    #include <cstdio>
    #include <iostream>
    using namespace std;
    int main(){
        int T; scanf("%d", &T);
        while(T--){
            int l, r, d; scanf("%d%d%d", &l, &r, &d);
            if(d < l) printf("%d
    ", d);
            else printf("%d
    ", d * (r / d + 1));
        }
        return 0;
    }
    

    B. Accordion

    找到头尾的([:)(:]),然后统计中间有几个(|)即可。

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    using namespace std;
    const int N = 500010;
    int n;
    char s[N];
    int main(){
        scanf("%s", s + 1);
        n = strlen(s + 1);
        int l = 1, r = n, cnt = 0;
        while(l <= n && s[l] != '[') l++;
        while(r && s[r] != ']') r--;
        while(l <= n && s[l] != ':') l++;
        while(r && s[r] != ':') r--;
        if(l >= r) puts("-1");
        else{
            for(int i = l; i <= r; i++)
                if(s[i] == '|') cnt++;
            printf("%d
    ", 4 + cnt);
        }
        
        
        return 0;
    }
    

    C. Division and Union

    发现可以竖着一条线将所有线分开成两部分,则两边任意选都可以。那么我们就可以找到这个条线。把线段按左端点排序,每次如果有交集就合并,没有交集,我们就找到了一个"断点"。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    typedef pair<int, int> PII;
    const int N = 100010;
    int n, l[N], r[N];
    PII a[N];
    int main(){
        int T; scanf("%d", &T);
        while(T--){
            scanf("%d", &n);
            for(int i = 1; i <= n; i++){
                scanf("%d%d", l + i, r + i);
                a[i].first = l[i];
                a[i].second = r[i];
            }
            sort(a + 1, a + 1 + n);
            int rr = a[1].second, loc = 0;
            for(int i = 2; i <= n; i++){
                if(a[i].first <= rr)
                    rr = max(rr, a[i].second);
                else { loc = rr; break; }
            }
            if(!loc) printf("-1");
            else for(int i = 1; i <= n; i++)
                if(r[i] <= rr) printf("1 ");
                else printf("2 ");
            puts("");
        }
        return 0;
    }
    

    D. GCD Counting

    树形(dp)(100000)以内的每个数因子不超过(256)个(最多(2 ^ 3 * 3 * 5 * 7 * 9 * 13 * 19 > 100000)

    首先把每个读入的权值质因数分解,两个数必须有质因子(gcd)才不会$ = 1(。存在一条边)(u, v)(,若)u(和)v$之间有相同的质因子则可以合并,但注意下一次合并必须也有这个质因子...

    所以设计(f[i][j])(i)个点为根节点,以第(j)个质因子为保障的最大长度。更新显然,如果遇到新的更新,答案可以更新,现在的 + 可以更新的。

    所以... 虽然看似会炸掉,但是还是卡过了...

    #include <cstdio>
    #include <iostream>
    #include <vector>
    using namespace std;
    const int N = 200010;
    int n, a[N], ans = 1;
    vector<int> G[N], p[N], f[N];
    bool success = true;
    void dfs(int u, int last){
        for(int i = 0; i < G[u].size(); i++){
            int v = G[u][i];
            if(v == last) continue;
            dfs(v, u);
            for(int j = 0; j < p[u].size(); j++){
                for(int k = 0; k < p[v].size(); k++){
                    if(p[u][j] == p[v][k]){
                        ans = max(ans, f[u][j] + f[v][k]);
                        f[u][j] = max(f[u][j], f[v][k] + 1);
                    }
                }
            }
        }
    }
    int main(){
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) {
            scanf("%d", a + i);
            if(a[i] != 1) success = false;
            int x = a[i];
            for(int j = 2; j * j <= a[i]; j++){
                if(x % j == 0){
                    p[i].push_back(j);
                    f[i].push_back(1);
                    while(x % j == 0) x /= j;
                }
            }
            if(x > 1) p[i].push_back(x), f[i].push_back(1);
        
        }
        for(int i = 1; i < n; i++){
            int u, v; scanf("%d%d", &u, &v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        if(success) puts("0");
        else{
            dfs(1, 0);
            printf("%d", ans);
        }
        return 0;
    }
    

    E. Polycarp's New Job

    两者都符合交换律,所以我们交换使得:

    (x <= y)(h <= w)

    维护(x)(y)的最大值,(max\_x)(max\_y)

    检查$max_x <= h $ (&&) (max\_y <= w)即可。

    显然,如果符合$max_y <= h $ (&&) (max\_x <= w),那么前者显然必然成立:

    如果不符合,前者也有可能成立。

    #include <cstdio>
    #include <iostream>
    using namespace std;
    const int N = 500010;
    int n, a = 0, b = 0;
    int main(){
        scanf("%d", &n);
        for(int i = 1; i <= n; i++){
            char ch; cin >> ch;
            if(ch == '+'){
                int x, y; scanf("%d%d", &x, &y);
                if(x > y) swap(x, y);
                a = max(a, x);
                b = max(b, y);
            }else{
                int h, w; scanf("%d%d", &h, &w);
                if(h > w) swap(h, w);
                if(a <= h && b <= w) puts("YES");
                else puts("NO");
            }
        }
        return 0;
    }
    
  • 相关阅读:
    HDU 2054 A == B ?(找小数点)
    javaWeb_使用标签库简化jsp
    EC2的维护更新-总结篇及有效经验分享
    SSLStrip 终极版 —— location 瞒天过海
    华为部分真机调试无法显示log问题解决
    LeetCode
    Tcl脚本调用高层API实现仪表使用和主机创建配置的自己主动化測试用例
    web工程调用hadoop集群1.2
    3DShader之移位贴图(Displacement Mapping)
    Java 学习第一天
  • 原文地址:https://www.cnblogs.com/dmoransky/p/11291519.html
Copyright © 2011-2022 走看看