Codeforces Round #665 (Div. 2) 题解

Codeforces Round #665 (Div. 2)

A. Distance and Axis

题目描述:

现在在一个数轴上给出一个A点,并要求你找出一个满足的点B,使得OB和AB满足:
∣ O A − A B ∣ = k |OA - AB| = k OAAB=k
n是给出A的坐标,k是上述距离。如果没有办法找到,允许改变A的坐标,即对A的坐标值+1或者-1。

问要找到这个B点需要进行多少次操作。

题解:

这个题目分为这样几种情况考虑:

  • n = 0,这时ans = k因为A点和原点重合,所以说我们就需要找到满足长度为k的OA的长度然后让B和A重合

  • k = 0,这时ans = ((n & 1) ? 1 : 0)B点取中点,但是要考虑是不是偶数长度,否则要+1

  • k > n,这时ans = k - n(这个时候就是和第一种情况差不多,因为我们对于确定的n而言,我们能取到的最大k值就是n,所以只需要放大到k就可以满足

  • k < n,这就有点意思了,我们注意到,k和n奇偶性相同时,这时的答案就是0,但是如果不同,那么答案就是1了,这个可以多试几个数据然后写一下可能产生的情况总结规律。

AC代码:

#include<iostream>
using namespace std;
int main()
{
    int t;
    cin >> t;
    while(t--){
        int n,k;
        cin >> n >> k;
        if(n == 0) cout << k << endl;
        else if(k == 0) cout << ((n & 1) ? 1 : 0) << endl;
        else if(k == n) cout << 0 << endl;
        else if(k > n) cout << k - n << endl;
        else if(k < n){
            if((n % 2) == (k % 2)){
                cout << 0 << endl;
            }
            else{
                cout << 1 << endl;
            }
        }
    }
    return 0;
}

B.Ternary Sequence

题目描述:

给定了两个序列a,b,其中的元素都是0,1,2组成的,在a序列中0,1,2的数目分别是x1,y1,z1;b序列中的0,1,2的数目分别是x2,y2,z2。现在给出了一个序列c,满足以下的条件:
c i = a i ∗ b i , a i > b i c_i = a_i * b_i,a_i > b_i ci=aibi,ai>bi

c i = 0 , a i = b i c_i = 0,a_i = b_i ci=0,ai=bi

c i = − a i ∗ b i , a i < b i c_i = -a_i * b_i,a_i < b_i ci=aibi,ai<bi

现在要求你写出c的元素之和的最大值。

题解:

这个题目我们可以贪心的去想,我们尽可能让z1和y2匹配,并且尽可能减少z2和y1的匹配。

那么这个题就可以先凑出最大的z1和y2的匹配,然后z1和z2抵消一次,z2和x1抵消一次,这样我们可以得到z2的最小值,然后我们y1和y2抵消一次,然后y1和x2抵消一次,这样得到的就是y1的最小值,然后匹配y1和z2。

AC代码

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define ll long long
int main()
{
    int t;
    cin >> t;
    while(t--){
        ll x1,x2,y1,y2,z1,z2,ans = 0;
        cin >> x1 >> y1 >> z1 >> x2 >> y2 >> z2;
        ll temp = min(z1,y2); //注意存一下值,因为接下来的z1和y2的值都改变了,这会影响到min的值,后面的同理
        ans = temp;
        z1 -= temp;
        y2 -= temp;
        ll flag = min(z1,z2);
        z1 -= flag;
        z2 -= flag;
        ll cnt = min(x1,z2);
        z2 -= cnt;
        y1 -= min(y1,x2);
        y1 -= min(y1,y2);
        ans -= min(y1,z2);
        cout << ans * 2 << endl;
    }
    return 0;
}

C.Mere Array

题目描述:

给出了一个既定的序列a,现在规定一种排列方式:对于这个序列中的两个元素,如果满足:
g c d ( a i , a j ) = m i n ( a ) gcd(a_i,a_j) = min(a) gcd(ai,aj)=min(a)
那么就可以交换两个元素的位置,现在需要你判断对于一个给出的序列a,能否通过这样的操作使得a变成递增序列。

题解:

既然两个元素的最大公约数是a序列中最小的元素时才能交换次序,那么就是说只有这两个元素是最小值的倍数才满足条件,那么我们可以先把正确的序列排出来,然后和原序列比较,如果位置不正确而且不是最小值倍数的话,那就一定不能交换出正确序列。反之如果对于每个错误的数都是最小值倍数,那么就一定可以通过交换次序得出正确的序列。

AC代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn = 1e5 + 10;
ll a[maxn],b[maxn];
bool cmd(ll a,ll b)
{
    if(a != b) return a < b;
}
int main()
{
    int t;
    cin >> t;
    while(t--){
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        int n;
        ll min_a = 0x3f3f3f3f;
        cin >> n;
        for(int i = 1;i <= n;i++){
            cin >> a[i];
            b[i] = a[i];
            min_a = min(a[i],min_a);
        }
        bool flag = 1;
        sort(a + 1,a + 1 + n,cmd);
        for(int i = 1;i <= n;i++){
            if(a[i] != b[i] && b[i] % min_a != 0){
                flag = 0;
                break;
            }
        }
        if(flag) cout << "YES" << endl;
        else cout << "NO" << endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CUCKyrie

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值