Codeforces Round #730 (Div. 2)

Codeforces Round #730 (Div. 2)

A

思路:

  • GCD(a,b)=GCD(a−b,b) if a>b
  • 因为 a-b是不变的
  • 所以最大公因数 为 a-b 特别a == b时 无限大
  • 最小步数 选离a最近的公因数倍数即可
    代码
#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
ll n, m;
 
int main() {
    int test;
    cin >> test;
    while(test--) {
        cin >> n >> m;
        ll x = abs(n-m);
        if(!x) printf("0 0\n");
        else {
            ll y = min(x-n%x, n%x);
            printf("%lld %lld\n", x, y);
        }
    }
    return 0;
}

B

思路:

  • 车辆数量将尽可能均匀地分布。
  • 即对于每个有效(i,j), |ai−aj|≤1
  • sum%n 为多出的 1 量车的数量
    代码
#include<iostream>
using namespace std;
const int N = 2e5+10;
typedef long long ll;
 
int n;
 
int main() {
    int test;
    cin >> test;
    while(test--) {
        cin >> n;
        ll sum = 0;
        for(int i = 0; i < n; ++i) {
            int x;
            cin >> x;
            sum += x;
        }
        ll ans = sum%n*(n-sum%n);
        printf("%lld\n", ans);
    }
    return 0;
}

C

思路

  • 看懂题目就好写了
  • 在c m p 中选 每次选择会使选到的数减v(不够变为0)
  • 把减到的数平均分给没变0成数(不包含本身)
  • 无限选直到选到 p 为结束
  • 暴力搜索模拟一遍即可
    代码
#include<iostream>
#include<cmath>
using namespace std;
const double eps = 1e-8;
double c, m, p, v;
double ans;
void dfs(double c, double m, double p, int setp, double sum) {
    
    if(abs(c) > eps) {
        if(c-v > eps) {
            if(m) dfs(c-v, m+v/2, p+v/2, setp+1, sum*c);
            else  dfs(c-v, 0    , p+v  , setp+1, sum*c);
        }
        else {
            if(m) dfs(0, m+c/2, p+c/2, setp+1, sum*c);
            else  dfs(0, 0    , p+c  , setp+1, sum*c);
        }
        
    }
    if(abs(m) > eps) {
        if(m-v > eps) {
            if(c) dfs(c+v/2, m-v, p+v/2, setp+1, sum*m);
            else  dfs(0    , m-v, p+v  , setp+1, sum*m);
        }
        else {
            if(c) dfs(c+m/2, 0, p+m/2, setp+1, sum*m);
            else  dfs(0    , 0, p+m  , setp+1, sum*m);
        }
    }
    ans += sum*p*setp;
}
 
int main() {
    int test;
    cin >> test;
    while(test--) {
        cin >> c >> m >> p >> v;
        ans = 0;
        dfs(c, m, p, 1, 1);
        printf("%.12lf\n", ans);
    }
    return 0;
}

D

思路

  • 因为初始密码可以为任意数并且在 n 的范围内
  • 设x为初始代码 每次变化变成 x1··x2···xn
  • y = x ^ x1
  • y ^ x = x ^ x ^ x1
  • x1 = x^y
  • 因为我们有n个查询,x 在 n 范围内
  • x1 的 由 x 决定 以此推理得
  • xi = x ^ x1 ^ x2 ^ x3… ^x(i-1)
  • 我们要不重不漏 只要使 x 由 0 累加 1
  • 最后如果原始密码是(x−1),那么第x次查询将等于当前密码。
    代码
#include<iostream>
#include<cstring>
using namespace std;
 
int n, k;
 
int main() {
    int test;
    cin >> test;
    while(test--) {
        cin >> n >> k;
        int x = 0, y, r;
        for(int i = 0; i < n; ++i) {
            y = x^i;
            cout << y << endl;
            x = x^y; // x++
            cin >> r;
            if(r) break;
        }
    }   
    // x = x1^x2^x3...
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

光—暗

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

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

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

打赏作者

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

抵扣说明:

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

余额充值