codeforce 刷题(三)

CodeForces 1325D Ehab the Xorcist

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

题解

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

  • \(u <= v\) 才可能有解,因为异或只会使和减小,毕竟两个数的二进制表示的相同位置上\(1 \bigoplus 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 \bigoplus t \bigoplus t = u\),表明序列:\(u\)\(t\)\(t\) 可能是解。观察样例1会发现,序列也有可能仅由两个数构成就可以啦,那么在什么情况下,只会用到两个数?假如 \(u \bigoplus t = u + t\),那么就能将\(u\)\(t\) 合并成一个数 $u \bigoplus 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 << "\n" << u << endl;
    }
    else {
        int t = (v - u) / 2;
        if ((u ^ t) == u + t) {
            cout << 2 << "\n" << u + t << " " << t << endl;
        }
        else {
            cout << 3 << "\n" << 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;
}
posted @ 2020-04-09 12:42  天之道,利而不害  阅读(278)  评论(0编辑  收藏  举报