Codeforces Round #676 (Div. 2)

题目链接

A. XORwice

题意:给定两个整数a, b,对任意的x,求(a⊕x) + (b⊕x)的最小值。
题解:如果 a 和 b 的某一数位是相同的(都为0或都为1),那么x只要在这一位取相同的值就可以让答案的这一数位为0。如果 a 和 b 的某一数位不同(一个是1一个是0),那么无论x在这一位取什么值答案的这一数位都会是1 。

#include <bits/stdc++.h>
using namespace std;
 
int main()
{
    int T;
    cin >> T;
    for (int cas = 0; cas < T; cas++) {
        int res = 0;
        int a, b, cnt = 0;
        cin >> a >> b;
        while (a != 0 && b != 0) {
            int ta = a & 1, tb = b & 1;
            a >>= 1; b >>= 1;
            if (ta != tb) {
                res += (1 << cnt);
            }
            cnt++;
        }
        res += ((a << cnt) + (b << cnt));
        cout << res << endl;
    }
    return 0;
}

B. Putting Bricks in the Wall

题意:给定一个 n×n 的矩阵, 矩阵中的每个元素都是0或1(除了起点和终点),(1,1) 是起点, (n,n)是终点。从起点出发前要选择走0或者走1,如果选0,那么只能走矩阵中值为0的格子,选1只能走值为1的格子。你最多只能翻转两个格子的值(0到1或1到0),使得从起点无法走到终点。
题解:只要让起点旁的两个元素都为0,终点旁的两个元素都为1,或者让起点旁的两个元素都为1,终点旁的两个元素都为0,这时从起点必然走不到终点。情况很少,穷举即可。

#include <bits/stdc++.h>
using namespace std;
 
char arr[205][205];
int n;
 
void changeA() {
    cout << 1 << ' ' << 2 << endl;
}
void changeB() {
    cout << 2 << ' ' << 1 << endl;
}
void changeC() {
    cout << n-1 << ' ' << n << endl;
}
void changeD() {
    cout << n << ' ' << n-1 << endl;
}
 
 
int main()
{
    int T;
    cin >> T;
    for (int cas = 0; cas < T; cas++) {
        cin >> n;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                cin >> arr[i][j];
            }
        }
 
        int a = arr[0][1] - '0', b = arr[1][0] - '0';
        int c = arr[n-2][n-1] - '0', d = arr[n-1][n-2] - '0';
        int cnt = 0;
        if (a == 0 && b == 0) {
            if (d == 0) cnt++;
            if (c == 0) cnt++;
            cout << cnt << endl;
            if (c == 0) changeC();
            if (d == 0) changeD();
        } else if (a == 0 && b == 1) {
            if (c == d) cnt = 1;
            else cnt = 2;
            cout << cnt << endl;
            if (c == 0 && d == 0) changeA();
            else if (c == 1 && d == 1) changeB();
            else if (c == 0 && d == 1) {
                changeA();
                changeD();
            }else if (c == 1 && d == 0) {
                changeA();
                changeC();
            }
        } else if (a == 1 && b == 0) {
            if (c == d) cnt = 1;
            else cnt = 2;
            cout << cnt << endl;
            if (c == 0 && d == 0) changeB();
            else if (c == 1 && d == 1) changeA();
            else if (c == 0 && d == 1) {
                changeA();
                changeC();
            }else if (c == 1 && d == 0) {
                changeA();
                changeD();
            }
        } else if (a == 1 && b == 1) {
            if (d == 1) cnt++;
            if (c == 1) cnt++;
            cout << cnt << endl;
            if (c == 1) changeC();
            if (d == 1) changeD();
        }
    }
 
    return 0;
}

C. Palindromifier

题意:给定一个长度为n的字符串s。你可以进行两种操作,使得该字符串变为一个回文串。操作1:选择一个 i (2 ≤ i ≤ n−1),将 s2 到 si 的字符串反转后加在原字符串的最前面。(R i)操作2:选择一个 i (2 ≤ i ≤ n−1),将 si 到 sn-1 的字符串反转后加在原字符串的最后面。(L i)
题解:设一个字符串为 abc (a、b、c可替换成其他的字符串)。第一步:R n-1 可得到 abcb 。第二步:L n 可得到 cbabcb 。第三步:L 2 可得到 bcbabcb 。

#include <bits/stdc++.h>
using namespace std;
 
int main()
{
    string s;
    cin >> s;
    cout << 3 << endl;
    cout << "R " << s.size() - 1 << endl;
    cout << "L " << s.size() << endl;
    cout << "L " << 2 << endl;
    return 0;
}

D. Hexagons

题意:给定一个二维蜂窝图,每个格子可以向六个方向移动,每个方向有不同的权值。给出一个格子的坐标(x, y) 问从 (0,0) 到 (x, y) 的最小花费。
题解:c1方向可以直接按c1走,也可以通过c2和c6走到,取最小值,即是c1方向的最小权值。其他方向同理。判断目标点的x和y的值,就可以得出目标点在哪个象限(如x>0且y>0就是第一象限),不同象限可以通过不同的方向走到,分类讨论即可。

#include <bits/stdc++.h>
using namespace std;
#define ll long long
 
int main()
{
    int T; cin >> T;
    for (int cas = 0; cas < T; cas++) {
        int x, y;
        cin >> x >> y;
        ll c[7];
        for (int i = 1; i <= 6; i++) cin >> c[i];
        c[1] = min(c[1], c[6] + c[2]);
        c[2] = min(c[2], c[1] + c[3]);
        c[3] = min(c[3], c[2] + c[4]);
        c[4] = min(c[4], c[3] + c[5]);
        c[5] = min(c[5], c[4] + c[6]);
        c[6] = min(c[6], c[5] + c[1]);
        ll ans = 0;
        if (x >= 0 && y >= 0) {
            if (x > y) ans = y * c[1] + (x - y) * c[6];
            else ans = x * c[1] + (y - x) * c[2];
        } else if (x <= 0 && y <= 0) {
            if (x < y) ans = -y * c[4] + (y - x) * c[3];
            else ans = -x * c[4] + (x - y) * c[5];
        } else if (x <= 0 && y >= 0) {
            ans = y * c[2] - x * c[3];
        } else {
            ans = x * c[6] - y * c[5];
        }
        cout << ans << endl;
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值