zoukankan      html  css  js  c++  java
  • Codeforces Round #400 (Div. 1 + Div. 2, combined)——ABCDE

    题目戳这里

    A.A Serial Killer

    题目描述似乎很恶心,结合样例和样例解释猜测的题意

    使用C++11的auto可以来一手骚操作

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int n;
    
    string s[4];
    
    map <string, int> p;
    
    int main() {
        cin >> s[0] >> s[1];
        p[s[0]] = p[s[1]] = 1;
        cin >> n;
        cout << s[0] << " " <<s[1] << endl;
        while(n --) {
            cin >> s[2] >> s[3];
            p[s[2]] ++, p[s[3]] ++;
            for(auto iter : p)
                if(iter.second == 1) cout << iter.first << " ";
            puts("");
        }
        return 0;
    }
    View Code

    其实等价于这样写

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int n;
    
    string s[4];
    
    map <string, int> p;
    
    int main() {
        cin >> s[0] >> s[1];
        p[s[0]] = p[s[1]] = 1;
        cin >> n;
        cout << s[0] << " " <<s[1] << endl;
        while(n --) {
            cin >> s[2] >> s[3];
            p[s[2]] ++, p[s[3]] ++;
            for(map <string, int>::iterator iter = p.begin();iter != p.end();iter ++)
                if(iter -> second == 1) cout << iter -> first << " ";
            puts("");
        }
        return 0;
    }
    View Code

    B.Sherlock and his girlfriend

    很蠢的一题,质数标1,合数标2就好了

    #include <bits/stdc++.h>
    
    #define rep(i, j, k) for(int i = j;i <= k;i ++)
    
    #define rev(i, j, k) for(int i = j;i >= k;i --)
    
    using namespace std;
    
    typedef long long ll;
    
    const int maxn = 100010;
    
    int n, a[maxn];
    
    int main() {
        ios::sync_with_stdio(false);
        cin >> n;
        if(n < 3) puts("1");
        else puts("2");
        for(int i = 2;i <= n + 1;i ++)
            if(a[i] != 2) {
                a[i] = 1;
                for(int j = i << 1;j <= n + 1;j += i)
                    a[j] = 2;
            }
        for(int i = 2;i <= n + 1;i ++)
            printf("%d ", a[i]);
        return 0;
    }
    View Code

    C.Molly's Chemicals

    有那么一点意思的题目

    求有多少段连续子段和为k的非负power

    显然k为2的话,大概能2^0 - 2^50左右吧

    所以直接枚举 k^p 即可

    偷懒套个map,复杂度O(n(logn)^2)

    注意:

    1.非负power,包括1

    2. |k| = 1 特判,否则死循环

    #include <bits/stdc++.h>
    
    #define rep(i, j, k) for(int i = j;i <= k;i ++)
    
    #define rev(i, j, k) for(int i = j;i >= k;i --)
    
    using namespace std;
    
    typedef long long ll;
    
    int n, t;
    
    ll k, s[100010];
    
    map <ll, int> p;
    
    int main() {
        ios::sync_with_stdio(false);
        int x;
        cin >> n >> t;
        rep(i, 1, n) cin >> x, s[i] = s[i - 1] + x;
        for(ll j = 1;abs(j) <= 100000000000000ll;j *= t) {
            p.clear(), p[0] = 1;
            rep(i, 1, n) {
                k += p[s[i] - j];
                p[s[i]] ++;
            }
            if(t == 1 || (t == -1 && j == -1)) break;
        }
        cout << k;
        return 0;
    }
    View Code

    D.The Door Problem

    应该注意到each door is controlled by exactly two switches

    所以显然对于一开始锁上的门,只能选择一个开关

    一开始打开的门,可以选择都不选或者都选

    于是我们可以想到2-sat来解决

    实际上2-sat也的确可以解决

    但是我们注意到这个2-sat的特殊性

    每组中的两个选择在某种程度上是等价的

    而我们平时做的 Ai 与 Ai’ 是不等价的

    两个选择等价意味着连的边已经是无向边

    即若有Ai -> Aj,则必有Aj -> Ai

    这样就不需要再tarjan

    直接并查集就可以解决了

    #include <cstdio>
    
    const int maxn = 100010;
    
    int n, m, f[maxn << 1], a[2][maxn];
    
    bool op[maxn];
    
    int find_(int x) {
        if(f[x] != x) return f[x] = find_(f[x]);
        return x; 
    }
    
    void union_(int x, int y) {
        x = find_(x), y = find_(y);
        if(x != y) f[x] = y;
    }
    
    int main() {
        scanf("%d %d", &n, &m);
        for(int i = 1;i <= n;i ++) scanf("%d", &op[i]);
        for(int k, j, i = 1;i <= m;i ++) {
            scanf("%d", &j);
            while(j --) {
                scanf("%d", &k);
                if(a[0][k]) a[1][k] = i;
                else a[0][k] = i;
            }
        }
        for(int i = m << 1;i;i --) f[i] = i;
        for(int i = 1;i <= n;i ++)
            if(op[i]) union_(a[0][i], a[1][i]), union_(a[0][i] + m, a[1][i] + m);
            else      union_(a[0][i], a[1][i] + m), union_(a[0][i] + m, a[1][i]);
        for(int i = 1;i <= m;i ++)
            if(find_(i) == find_(i + m)) {
                puts("NO");
                return 0;
            }
        puts("YES");
        return 0;    
    }
    View Code

    E.The Holmes Children

    手动计算发现 f 函数为欧拉函数

    gcd(x, y) = 1

    x + y = n

    => gcd(x, x + y) = 1 即 gcd(x, n) = 1 

    g(n) = n ,剩下部分很好解决

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    
    const int mod_ = 1e9 + 7;
    
    ll f(ll x) {
        ll ret = x;
        for(ll i = 2;i * i <= x;i ++)
            if(x % i == 0) {
                ret /= i, ret *= (i - 1);
                while(x % i == 0) x /= i;
            }
        if(x != 1) ret /= x, ret *= (x - 1);
        return ret;
    }
    
    int main(){
        ll n, k;
        cin >> n >> k;
        k = (k + 1) >> 1;
        for(int i = 1;i <= k;i ++) {
            n = f(n);
            if(n == 1) break;
        }
        cout << n % mod_; 
        return 0;
    }
    View Code
  • 相关阅读:
    as3 return语句中的运算符
    AIR custom ApplicationUpdaterUI
    Flash Builder 无法连接到应用程序以访存概要分析数据
    Android的所有权限说明
    Tomcat数据源配置
    hibernate 延迟加载(懒加载)
    Android SQLite数据库操作
    Android下载文本文件和mp3文件
    JPA注解
    Android Intent传值且实现窗体跳转
  • 原文地址:https://www.cnblogs.com/ytytzzz/p/6836564.html
Copyright © 2011-2022 走看看