zoukankan      html  css  js  c++  java
  • codeforce 刷题(三)

    CodeForces 1325D Ehab the Xorcist

    题目:https://vjudge.net/problem/CodeForces-1325D

    题解

    重点在于怎么使用异或运算,首先

    • (u <= v) 才可能有解,因为异或只会使和减小,毕竟两个数的二进制表示的相同位置上(1 igoplus 1 = 0)
    • (u)(v) 肯定同奇或者同偶才有解,因为异或后是奇数,说明这些数中的奇数个数也是奇数,它们的和肯定也是奇数,具体一点的说,考虑它们的二进制表示,(u) 是奇数代表着二进制末尾为1的数有奇数个,然后整数相加等于它们的二进制相加,得到的和用二进制表示的话,末尾肯定也是1,所以和是个奇数。偶数同理

    然后分类讨论,

    • (u = v),输出(u)
    • (u < v),因为(u)(v) 同奇偶性,故 (v - u) 必定是个偶数,可以将它们的差拆分成两个相等的数。令 (v - u = 2 * t),有 (u + t + t = v)(u igoplus t igoplus t = u),表明序列:(u)(t)(t) 可能是解。观察样例1会发现,序列也有可能仅由两个数构成就可以啦,那么在什么情况下,只会用到两个数?假如 (u igoplus t = u + t),那么就能将(u)(t) 合并成一个数 $u igoplus t $

    注意0,0的样例输出的是0;还有爆int

    int main()
    {
        long long u, v;
        cin >> u >> v;
    
        if (u > v || (u + v) & 1) {
            puts("-1");
        }
        else if (v == u) {
            if (!v) puts("0");
            else cout << 1 << "
    " << u << endl;
        }
        else {
            int t = (v - u) / 2;
            if ((u ^ t) == u + t) {
                cout << 2 << "
    " << u + t << " " << t << endl;
            }
            else {
                cout << 3 << "
    " << u << " " << t << " " << t << endl;
            }
        }
    
        return 0;
    }
    

    CodeForces 1321C Remove Adjacent

    给一个字符串,每次操作能删除一个字符 当且仅当 它的相邻字符是字母表位置的前一个字符,比如:b的前一个字符在字母表中是a,求最大操作次数

    题解

    显然先删除在字母表中顺序靠后的字符最优,理解题意后,很自然的想法。

    for循环的话要正向来一遍,反向来一遍,比如样例:bbbabbb

    int main()
    {
        int n;
        string s;
    
        cin >> n >> s;
    
        int m = s.size();
        char ms[200];
    
        for (char a = 'z'; a > 'a'; a--) {
            int t = 0;
            char last = s[0];
    
            // 正向
            myfor(i, 0, m) {
                if (s[i] == a) {
                    if ((i > 0) && (last - 'a' == a - 'a' - 1)) continue;
                    if ((i < m - 1) && (s[i + 1] - 'a' == a - 'a' - 1) continue;
                }
                last = ms[t++] = s[i];
            }
            m = t;
            myfor(i, 0, t) s[i] = ms[i];
    
            // 反向
            t = 0;
            last = s[m - 1];
            for (int i = m - 1; i >= 0; --i) {
                if (s[i] == a) {
                    if ((i > 0) && (s[i - 1] - 'a' == a - 'a' - 1)) continue;
                    if ((i < m - 1) && (last - 'a' == a - 'a' - 1)) continue;
                }
                last = ms[t++] = s[i];
            }
    
            m = t;
            myfor(i, 0, t) s[i] = ms[i];
        }
    
        cout << n - m << endl;
        return 0;
    }
    
  • 相关阅读:
    2014-04-23 总结
    14-5-13
    PHP
    14-5-8
    ajax
    14-5-6
    14-5-5
    PHP初解
    14-4-30
    14-4-29
  • 原文地址:https://www.cnblogs.com/zgglj-com/p/12666141.html
Copyright © 2011-2022 走看看