zoukankan      html  css  js  c++  java
  • ICPC 2019 Central Russia(9/11)

    ICPC Central Russia Regional Contest (CRRC 19)

    A. Green tea

    签到题

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 1e6 + 5;
    typedef long long LL;
    int a, b;
    int main() {
        cin >> a >> b;
        int res1, res2;
        int minn = 0x3f3f3f3f;
        for (int i = 0; i <= 1000; i++) {
            for (int j = 0; j <= 1000; j++) {
                if(i*a+j*b==80*(i+j)&&((i+j)!=0)){
                    if(i+j<minn){
                        res1 = i, res2 = j;
                        minn = i + j;
                    }
                }
            }
        }
        cout << res1 << ' ' << res2 << endl;
        return 0;
    }
    

    B. Mysterious Resistors

    大意:

    给出k组串联的电阻,每组电阻都是(r_i)和R并联,现在给出k个(r_i),以及总电阻,求R

    思路:

    因为有单调性,所以直接二分去找即可

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long LL;
    int const MAXN = 2e5 + 10;
    int n;
    double m;
    double r[MAXN];
    bool check(double mid) {
        double sum = 0;
        for (int i = 1; i <= n; i++) {
            sum += r[i] / (1.0 + r[i] / mid);
        }
        return sum > m;
    }
    int main() {
        cin >> n >> m;
        for (int i = 1; i <= n; i++) {
            cin >> r[i];
        }
        double l = 0, r = 1e5;
        while (r - l > 1e-8) {
            double mid = (l + r) / 2;
            if (check(mid))
                r = mid;
            else
                l = mid;
        }
        printf("%.8lf
    ", l);
        return 0;
    }
    

    C. Emoticons

    大模拟。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long LL;
    int const MAXN = 2e5 + 10;
    int n, m, T;
    map<char, int> num;
    unordered_map<char, string> mp;
    vector<char> f;
    int main() {
        string s;
        cin >> s;
        mp['\'] = ":-\";
        f.push_back('\');
        mp['P'] = ":-P";
        f.push_back('P');
        mp['D'] = ":D";
        f.push_back('D');
        mp['C'] = ":C";
        f.push_back('C');
        mp['8'] = "8-0";
        f.push_back('8');
        mp['E'] = ":-E";
        f.push_back('E');
        mp['%'] = "%0";
        f.push_back('%');
        mp['X'] = ":-X";
        f.push_back('X');
        mp['~'] = ":~(";
        f.push_back('~');
        mp['['] = "[:|||:]";
        f.push_back('[');
        mp['0'] = ":-0";
        f.push_back('0');
        mp['|'] = ":-|";
        f.push_back('|');
    
        for (int i = 0; i < s.size(); i++) {
            num[s[i]]++;
            // cout << s[i] << endl;
        }
        for (int v = 0; v < f.size(); v++) {
            char fl = f[v];
            if (num[fl]) {
                string t = mp[fl];
                int d = num[fl];
                for (int i = 0; i < d; i++) {
                    // cout << fl << " " << t << endl;
                    cout << t << endl;
                }
                for (int i = 0; i < t.size(); i++) {
                    num[t[i]] -= d;
                }
            }
        }
        if (num[';'] && num[')']) {
            int d = min(num[';'], num[')']);
            for (int i = 0; i < d; i++) {
                cout << ";-)" << endl;
            }
            num[';'] -= d;
            num['-'] -= d;
            num[')'] -= d;
        }
        if (num[';'] && num['(']) {
            int d = min(num[';'], num['(']);
            for (int i = 0; i < d; i++) {
                cout << ";-(" << endl;
            }
            num[';'] -= d;
            num['-'] -= d;
            num['('] -= d;
        }
        if (num[')']) {
            int d = num[')'];
            for (int i = 0; i < d; i++) {
                cout << ":)" << endl;
            }
            num[':'] -= d;
            num[')'] -= d;
        }
        if (num['(']) {
            int d = num['('];
            for (int i = 0; i < d; i++) {
                cout << ":(" << endl;
            }
            num[':'] -= d;
            num['('] -= d;
        }
        cout << "LOL" << endl;
        return 0;
    }
    

    D. Power play

    大意:

    给出两个数a和b,范围为1e4

    现在要求求出一个1e18以内的数,使得(a^x==x^b)

    思路:

    1e18是个幌子,可以发现x不会超过1e4,所以直接暴力枚举即可

    #include <bits/stdc++.h>
    
    #define int long long
    using namespace std;
    
    inline int read() {
        int s = 0, w = 1;
        char ch = getchar();
        while (ch < '0' || ch > '9') {
            if (ch == '-') w = -1;
            ch = getchar();
        }
        while (ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
        return s * w;
    }
    
    int const MAXN = 2e5 + 10;
    int n, m, T, a, b;
    
    long double eps = 1e-8;
    
    signed main() {
        a = read(), b = read();
        long double ai = a * 1.0, bi = b * 1.0;
        int flg = 0;
        for (int i = 1; i <= 1e6; ++i) {
            if (fabs(bi * log((long double)i) - (long double)i * log((long double)a)) < eps) {
                cout << i;
                flg = 1;
                break;
            }
        }
        if (!flg) cout << 0;
        return 0;
    }
    

    E. Printed circuit board

    gugugu

    F. A word game

    sg函数裸题

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 1e6 + 5;
    typedef long long LL;
    string s;
    int a[30];
    int f[100];
    int sg(int x) {
        if (f[x] != -1) return f[x];
        unordered_set<int> S;
        if (x >= 1) S.insert(sg(x - 1));
        if (x >= 2) S.insert(sg(x - 2));
        if (x >= 3) S.insert(sg(0));
        for (int i = 0;; i++) {
            if (!S.count(i)) return f[x] = i;
        }
    }
    
    int main() {
        cin >> s;
        memset(f, -1, sizeof f);
        for (int i = 0; i < s.size(); i++) {
            a[s[i] - 'A']++;
        }
        int res = 0;
        f[0] = 0;
        for (int i = 0; i < 26; i++) {
            res ^= sg(a[i]);
        }
        if (res) cout << "Alice" << endl;
        else cout << "Bob" << endl;
        return 0;
    }
    

    G. Hourglass

    gugugu

    H. Men's showdown

    集合nim游戏裸题

    #include<bits/stdc++.h>
    
    using namespace std;
    
    int n, k;
    int const N = 1e2 + 10, M = 1e4 + 10;
    int s[N];
    int f[M];
    
    // 记忆化搜索求sg函数
    int sg(int x) {
        if (f[x] != 0) return f[x];
        unordered_set<int> S; 
        
        // 计算每个后继状态的sg值
        for (int i = 1; i <= 3; ++i) {
            int sum = s[i];
            if (x >= sum) S.insert(sg(x - sum));
        }
    
        // mex运算
        for (int i = 0; ; i++)
            if (!S.count(i)) return f[x] = i;
    }
    
    int main() {
        // 读入集合s
        s[1] = 1, s[2] = 5, s[3] = 13;
        int x;
        cin >> x;
        int res = sg(x);
        if (!res) cout << "1
    ";
        else cout << "2
    ";
        return 0;
    }
    

    I. Andrew and Python

    思路:

    交互题,给出一个n*n的棋盘,然后有一个目标点,现在可以进行3种操作:

    一种是询问目标点是否是某一个点

    一种是询问目标点是否在某一条线段上

    一种是询问目标点是否在某一个三角形上及内部

    思路:

    利用三角形询问进行二分,每次询问一半的三角形,到后面如果无法组成三角形,那么就利用线段进行二分

    最后可能会剩下1-3个点,直接暴力询问即可

    #include <bits/stdc++.h>
    
    #define int long long
    using namespace std;
    typedef pair<int, int> PII;
    
    inline int read() {
        int s = 0, w = 1;
        char ch = getchar();
        while (ch < '0' || ch > '9') {
            if (ch == '-') w = -1;
            ch = getchar();
        }
        while (ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
        return s * w;
    }
    
    int const MAXN = 2e5 + 10;
    int n, m, T;
    
    PII get_mid(PII x, PII y, PII z) {
        double res_x = (1.0 * x.first + 1.0 * y.first) / 2.0;
        double res_y = (1.0 * x.second + 1.0 * y.second) / 2.0;
        if (z.first < res_x)
            res_x = ceil(res_x);
        else
            res_x = floor(res_x);
        if (z.second < res_y)
            res_y = ceil(res_y);
        else
            res_y = floor(res_y);
        return {(int)res_x, (int)res_y};
    }
    
    int test(PII a, PII b, PII c) {
        if ((c.second - b.second) * (b.first - a.first) ==
            (b.second - a.second) * (c.first - b.first))
            return 1;
        else
            return 0;
    }
    
    int check(PII a, PII b, PII c) {
        if (!test(a, b, c)) {
            cout << "? 3 " << a.first << " " << a.second << " " << b.first << " "
                 << b.second << " " << c.first << " " << c.second << endl;
            fflush(stdout);
            string s;
            cin >> s;
            if (s == "Yes")
                return 1;
            else
                return 0;
        } else {
            if (a == b) {
                return 0;
            } else {
                cout << "? 2 " << a.first << " " << a.second << " " << b.first
                     << " " << b.second << endl;
                fflush(stdout);
                string s;
                cin >> s;
                if (s == "Yes")
                    return 1;
                else
                    return 0;
            }
        }
    }
    
    int check2(PII a, PII b, PII c) {
        int ab = (a.first - b.first) * (a.first - b.first) +
                 (a.second - b.second) * (a.second - b.second);
        int bc = (b.first - c.first) * (b.first - c.first) +
                 (b.second - c.second) * (b.second - c.second);
        int ac = (a.first - c.first) * (a.first - c.first) +
                 (a.second - c.second) * (a.second - c.second);
        if (ab < 4 && bc < 4 && ac < 4) return 0;
        return 1;
    }
    
    int Query(PII x) {
        cout << "? 1 " << x.first << " " << x.second << endl;
        fflush(stdout);
        string s;
        cin >> s;
        if (s == "Yes")
            return 1;
        else
            return 0;
    }
    
    void print(PII x) {
        cout << "! " << x.first << " " << x.second << endl;
        fflush(stdout);
    }
    
    signed main() {
        cin >> n;
        PII a, b, c;
        c = {1, 1}, a = {1, n}, b = {n, 1};
        if (!check(a, b, c)) c = {n, n};
        while (check2(a, b, c)) {
            PII mid = get_mid(a, b, c);
            if (check(a, c, mid)) {
                b = c, c = mid;
            } else {
                a = b, b = c, c = mid;
            }
        }
        if (Query(a)) {
            print(a);
        } else if (Query(b)) {
            print(b);
        } else if (Query(c)) {
            print(c);
        }
        return 0;
    }
    

    J. Something that resembles Waring's problem

    大意:

    给出一个数x,要求将其表示为不超过5个数的立方和的形式,x范围为1e100000

    思路:

    过于精妙....

    来自:https://www.cnblogs.com/hyheng/p/14264678.html

    图片.png

    python3写了一发没过 ,应该是科学计数法导致的精度丢失,长了个教训,高精度就用Python2

    n = input()
    n = int(n)
    r = n % 6
    r3 = r * r * r
    print('5')
    print('%d %d %d %d %d' %(r, ((n - r3) / 6 + 1), ((n - r3) / 6 - 1), (-(n - r3) / 6), (-(n - r3) / 6)))
    

    K. Parabolic sorting

    大意:

    给出n个不相等的数,要求将其排列为前降后升的序列,每次操作可以将相邻的两个点交换,问最小多少次交换可以完成

    思路:

    对于每个点,考虑将其放到前面下降的区间还是后面上升的区间

    如果放到前面区间,那么需要操作的就是前面比他小的数的个数

    如果放到后面区间,那么需要操作的就是后面比他小的个数

    所以每个点算一下前面后面的个数,取min,最后相加即可

    可以用树状数组,线段树来维护

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long LL;
    int const N = 5e5 + 10;
    LL c[N], n, a[N], l[N], r[N];
    vector<LL> v;
    unordered_map<LL, int> H;
    
    int lowbit(int x) { return x & -x; }
    
    void add(int x, int y) {
        for (int i = x; i <= n; i += lowbit(i)) c[i] += y;
    }
    
    LL query(int x) {
        LL res = 0;
        for (int i = x; i; i -= lowbit(i)) res += c[i];
        return res;
    }
    
    int main() {
        scanf("%lld", &n);
        memset(c, 0, sizeof c);
        v.clear();
        H.clear();
        for (int i = 1; i <= n; ++i) {
            scanf("%lld", &a[i]);
            v.push_back(a[i]);
        }
        sort(v.begin(), v.end());
        int cnt = 1;
        for (int i = 0; i < v.size(); ++i) H[v[i]] = cnt++;  // 离散化
        LL res = 0;
        for (int i = n; i >= 1; --i) {  // 计算每个H[a[i]]出现的次数
            r[i] = query(H[a[i]] - 1);  // 加上H[a[i]-1]出现的总次数
            add(H[a[i]], 1);            // 次数加一
        }
        for (int i = n; i >= 1; --i) {
            add(H[a[i]], -1);
        }
        for (int i = 1; i <= n; ++i) {  // 计算每个H[a[i]]出现的次数
            l[i] = query(H[a[i]] - 1);  // 加上H[a[i]-1]出现的总次数
            add(H[a[i]], 1);            // 次数加一
        }
        for (int i = 1; i <= n; ++i) {
            res += min(r[i], l[i]);
        }
        cout << res << endl;
        return 0;
    }
    
  • 相关阅读:
    C++中的函数名称粉碎机制和它的逆向应用
    C++中const关键字的功能总结
    探究printf函数对单精度浮点数的处理
    利用共用体和位段获得IEEE标准编码的浮点型数据各部分数值
    C++中使用switch..case语句的易出错陷阱和规避方法
    浮点型数据(float, double)存储IEEE标准解析和应用
    React实用技巧
    Web前端之iframe详解
    开源的api文档管理系统
    编写自己的代码库(css3常用动画的实现)
  • 原文地址:https://www.cnblogs.com/dyhaohaoxuexi/p/14461552.html
Copyright © 2011-2022 走看看