Codeforces Round #676 (Div. 2)

58 篇文章 0 订阅
35 篇文章 1 订阅

A. XORwice

题意:给两个数,找出一个x,使得(a⊕x) + (b⊕x) 最小。⊕表示异或。

思路:分解成二进制,如果相同位上的数相同,那么这个位异或之后两个都可以为0,那么就没有贡献了。相反如果不相等,那么不论x怎么取,这个位都没办法消除。所以要加上。

AC代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 4e5 + 10;
//const int N = 1e6+7;
const int mod = 1e9+7;
int t,n,m,k;
int a[N],b[N];
typedef long long ll;
int bit1[N];
int bit2[N];
 
signed main(){
    int t;
    cin>>t;
    while(t--){
        cin>>n>>k;
        int res = 0;
        int now = 1;
        for(int i = 0 ; i < 40 ; i ++){
            int t1 = n&1,t2 =k&1;
            n/=2;k/=2;
            if(t1 == t2){
            }else{
                res += now;
            }
            now <<= 1;
        }
        cout<<res<<endl;
    }
    return 0;
}

B. Putting Bricks in the Wall

题意:一个n*n的网格,只有01,除了起点和终点,要从起点走到终点,沿路只能走相同的数。也就是要么0要么1。现在要你改变最多两个数。使得他无路可走,也就是到不了终点。

思路:一看就知道,只要封住起点和终点边上的两个点的。就无路可走了。如果起点是00,那么让终点变成11。反之,如果起点是11,那么把终点变成00。如果起点是01,或者10,那么把他变成11,然后终点变成00。

AC代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 4e5 + 10;
//const int N = 1e6+7;
const int mod = 1e9+7;
int t,n,m,k;
int a[N],b[N];
typedef long long ll;
string s[2005];
 
signed main(){
    int t;
    cin>>t;
    while(t--){
        int n;cin>>n;
        for(int i = 1 ; i <= n ; i ++) cin>>s[i];
        int s1 = s[1][1];
        int s2 = s[2][0];
        int e1 = s[n][n-2];
        int e2 = s[n-1][n-1];
        if(s1 == s2){
            cout<<(e1==s1)+(e2==s1)<<endl;
            if(e1 == s2) cout<<n<<" "<<n-1<<endl;
            if(e2 == s2) cout<<n-1<<" "<<n<<endl;
        }else if(e1 == e2){
            cout<<(e1==s1)+(e2==s2)<<endl;
            if(e1 == s1) cout<<1<<" "<<2<<endl;
            if(e2 == s2) cout<<2<<" "<<1<<endl;
        }else{
            cout<<2<<endl;
            cout<<1<<" "<<2<<endl;
            if(e1 == s2) cout<<n<<" "<<n-1<<endl;
            if(e2 == s2) cout<<n-1<<" "<<n<<endl;
        }
    }
    return 0;
}

C. Palindromifier

题意:一个字符串,有两种操作,操作1:选择[2-k]的子串,反转复制到最前面。操作2:选择[k- n-1]的子串,反转复制到最后面。然后字符串会变成新字符串。现在要在30步以内,用这两种操作,造出一个回文串。

思路:我大意了,看错题了。我以为只能复制原字符串的子串。原来可以复制新字符串的子串。现在随便假设一个字符串abcd,先把c复制到后面。变成abcdc。然后再把中间全复制到前面,变成dcbabcdc,然后就只有一个字符对不上了。但是,这时候,c已经在第二个位置了。所以再把它复制到前面。变成cdcbabcdc。完成。更一般的表示就是:xsco -> xscoc -> ocsxscoc -> cocsxscoc

s可以是任意字符串,x,c,o都可以是任意字符。所以答案输出 R n-1 \n L n \n L 2就ok了

AC代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 4e5 + 10;
const int mod = 1e9+7;
int t,n,m,k;
int a[N],b[N],c[N];

signed main(){
    // test();
    int t = 1; //cin>>t;
    while(t--){
        string s;
        cin>>s;n = s.size();
        cout<<3<<endl;
        cout<<"R "<<n-1<<endl;
        cout<<"L "<<n<<endl;
        cout<<"L "<<2<<endl;
    }
    return 0;
}
/***
***/

D. Hexagons

题意:给定一个网格,但是这个网格是六边形的。其实还是二维的坐标。然后有六个方向可走,每个方向代价不同。 问走到x,y点代价最小是多少。

在这里插入图片描述
在这里插入图片描述

思路:就贪心呗。可以发现,每个方向,其实都可以被另外两个方向的替代。比如想往右上角走,可以先往右,然后往左上。所以,开局先把所有方向的代价更新一下,选择最小的代价。然后把整个图,分成四个象限去计算(x坐标得斜着看)。可以算出,x,y坐标各要改变多少。然后用刚刚算出来的代价去计算就好了。

在这里插入图片描述

AC代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 4e5 + 10;
const int mod = 1e9+7;
int t,n,m,k;
int a[N],b[N],c[N];
 
signed main(){
    // test();
    int t = 1; cin>>t;
    while(t--){
        int x,y;
        cin>>x>>y;
        int res = 0;
        for(int i = 1 ;i <= 6 ; i ++) cin>>c[i];
        int c_right = min(c[2],c[1]+c[3]);
        int c_down = min(c[3],c[2]+c[4]);
        int c_left = min(c[5],c[6]+c[4]);
        int c_up = min(c[6],c[1]+c[5]);
        int c_up_right = min(c[1],c_right+c_up);
        int c_down_left = min(c[4],c_down+c_left);
        if(x >= 0 && y >= 0){   // 第一象限
            int up = x;
            int right = y;
            int minn = min(up,right);
            res = c_up_right*minn; up -= minn; right -= minn;
            res += c_right*right+c_up*up;
        }else if(x >= 0 && y <= 0 ){  // 第二象限
            int up = x;
            int left = -y;
            res += c_left*left+c_up*up;
        }else if(x <= 0 && y <= 0 ){  // 第三象限
            int down = -x;
            int left = -y;
            int minn = min(down,left);
            res = c_down_left*minn; down -= minn; left -= minn;
            res += c_left*left+c_down*down;
        }else if(x <= 0 && y >= 0 ){  // 第四象限
            int down = -x;
            int right = y;
            res += c_right*right+c_down*down;
        }
        cout<<res<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值