Codeforces Round 1016 (Div. 3)

在这里插入图片描述

Codeforces Round 1016 (Div. 3)

A. Ideal Generator

AC code:

void solve() {   
    int n; cin >> n;
    if (n % 2) cout << "YES" << endl;
    else cout << "NO" << endl;
} 

B. Expensive Number

思路:

只要最小化分母元素即可,即删到只剩一位,成本必然为1;

显然要使得操作数最小,后缀0全部都要删除,再删除前缀中的所有非0数字,留一个即可

AC code:

void solve() {   
    string s; cin >> s;
    if (s.size() == 1) {
        cout << 0 << endl;
        return;
    }
    int cnt = 0;
    bool flag = false;
    for (int i = s.size() - 1; i >= 0; i --) {
        if (s[i] == '0') {
            if (!flag) cnt ++; 
        } else {
            flag = true;
            cnt ++;
        }
    }
    cout << cnt-1 << endl;
} 

C. Simple Repetition

题意:

给出数字n,数字n首尾相接k次组成“nnnnnn”,判断相接后的数字是否为素数

思路:

打表,发现只要k>1就一定是非素数,否则单独判断一下n是否为素数即可

是这样吗

实际上n=1是特殊的,对于1的不同相接元素是存在素数的,比如11

AC code:

iprime(int x) {
    if (x == 1) return false;
    for (int i = 2; i <= x / i; i ++) {
        if (x % i == 0) return false;
    } return true;
}

void solve() {  
    int n; cin >> n;
    string s = to_string(n);
    int k; cin >> k;
    if (n == 1) {
        int ca = 0;
        for (int i = 0; i < k; i ++) {
            ca += (LL)pow(10, i);
        } 
        if (iprime(ca)) cout << "Yes" << endl;
        else cout << "No" << endl;
        return;
    }
    if (k > 1) {
        cout << "No" << endl;
        return;
    }else if (k == 1) {
        if (iprime(n)) cout << "Yes" << endl;
        else cout << "No" << endl;
        return;
    } 
} 

D. Skibidi Table

题意:

ε=(´ο`*)))唉,被递归模拟创思了。

思路:

首先我们来看如何通过一个坐标来寻找到其位置的元素:

  • 我们可以将整个图看做多个由四个元素的方块叠成的,事实上也是这样的

    图的大小为 2 n ∗ 2 n 2^n*2^n 2n2n ,现在尝试将其四等分,那么每一块的最大元素为:

    左上 2 2 n − 2 , 右下 2 2 n − 2 ∗ 2 , 左下 2 2 n − 2 ∗ 3 , 右上 2 2 n − 2 ∗ 4 左上2^{2n- 2}, 右下2^{2n-2}*2, 左下2^{2n-2}*3, 右上2^{2n-2}*4 左上22n2,右下22n22,左下22n23,右上22n24

    划分四块的mid值为 2 n − 1 2^{n - 1} 2n1

    以此为条件,我们可以不断将当前需要寻找的{x,y}不断向左上角的{1,2,3,4}进行递归

    在递归过程中,四块元素都需要添加不同的值,例如左下元素是 2 2 n − 1 2^{2n-1} 22n1+1开始的,则在递归到左下时需要额外添加 2 2 n − 1 2^{2n-1} 22n1

    当n==1时,我们即可return找到的值

  • 同理,对于寻找大小为x的值的坐标

    我们的思路还是递归到最左上的{1,2,3,4},但有一点需要注意

    在递归求取{x,y}推x时,我们将坐标不断减少mid值来向初试四方块靠近

    但在x求取{x,y}时,由于我们的真实坐标是需要由最终推出的四元素坐标增加不同值得到的,所以递归过程中,

    一直这削减的是所求元素x的大小去向{1,2,3,4}靠近,而记录的坐标值是不断增加的

AC code:

int getd(int x, int y, int n) {
    if (n == 1) {
        if (x == 1 && y == 1) return 1;
        if (x == 1 && y == 2) return 4;
        if (x == 2 && y == 1) return 3;
        if (x == 2 && y == 2) return 2;
    }
    int mid = (1LL << n) / 2;
    if (x <= mid && y <= mid) return getd(x, y, n - 1);
    else if (x <= mid && y > mid) return getd(x, y - mid, n - 1) + (1LL << (2*n-2))*3;
    else if (x > mid && y <= mid) return getd(x - mid, y, n - 1) + (1LL << (2*n-2))*2;
    //else if (x >= mid && y >= mid) 
    return getd(x - mid, y - mid, n - 1) + (1LL << (2*n-2));
}

PII loc(int pos, int n) {
    if (n == 1) {
        if (pos == 1) return {1, 1};
        if (pos == 2) return {2, 2};
        if (pos == 3) return {2, 1};
        if (pos == 4) return {1, 2};
    }

    int mid = (1LL << n) / 2;
    int t = (1LL << (2*n - 2));
    if (pos >= 1 && pos <= t) {
        return loc(pos, n - 1);
    }
    else if (pos >= t + 1 && pos <= t*2) {
        auto [x, y] = loc(pos - t, n - 1);
        return {x + mid, y + mid};
    }
    else if (pos >= t*2+1 && pos <= t*3) {
        auto [x, y] = loc(pos - 2*t, n - 1);
        return {x + mid, y};
    }
    //else (pos >= t*3+1 && pos <= t*4) {
    auto [x, y] = loc((pos - 3*t), n - 1);
    return {x, y + mid};
}

void solve() { 
    int n, q;  
    cin >> n;
    cin >> q;
    while (q --) {
        string s; cin >> s;
        if (s[0] == '-') {
            int x, y; cin >> x >> y;
            cout << getd(x, y, n) << endl;
        } else {
            int pos; cin >> pos;
            auto [x, y] = loc(pos, n);
            cout << x << ' ' << y << endl;
        }
    }
} 

E. Min Max MEX

思路:

很典的二分,直接二分Mex的值,然后尽可能的分成k段

主要问题在check条件中记录Mex的过程中选择的方法,用set,umap的全被创思了

这里其实用一个普通数组即可实现了

int n, k;
int a[N];

bool check(int x) {
    int cnt = 0;
    int now = 0;
    vector<int> pos(x + 1, 0);

    for (int i = 1; i <= n; i ++) {
        if (a[i] < x && !pos[a[i]]) {
            now ++;
            pos[a[i]] = 1;
        }
        if (now >= x) {
            cnt ++;
            now = 0;
            for (int j = 0; j <= x; j ++) pos[j] = 0;
        }
    }

    return cnt >= k;
}

void solve() {   
    cin >> n >> k;
    for (int i = 1; i <= n; i ++) cin >> a[i];

    int l = 0, r = n, ans = 0;
    while (l < r) {
        int mid = l + r + 1 >> 1;
        if (check(mid)) l = mid;
        else r = mid - 1;
    }
    cout << l << endl;
} 
### Codeforces Round 927 Div. 3 比赛详情 Codeforces是一个面向全球程序员的比赛平台,定期举办不同级别的编程竞赛。Div. 3系列比赛专为评级较低的选手设计,旨在提供更简单的问题让新手能够参与并提升技能[^1]。 #### 参赛规则概述 这类赛事通常允许单人参加,在规定时间内解决尽可能多的问题来获得分数。评分机制基于解决问题的速度以及提交答案的成功率。比赛中可能会有预测试案例用于即时反馈,而最终得分取决于系统测试的结果。此外,还存在反作弊措施以确保公平竞争环境。 ### 题目解析:Moving Platforms (G) 在这道题中,给定一系列移动平台的位置和速度向量,询问某时刻这些平台是否会形成一条连续路径使得可以从最左端到达最右端。此问题涉及到几何学中的线段交集判断和平面直角坐标系内的相对运动分析。 为了处理这个问题,可以采用如下方法: - **输入数据结构化**:读取所有平台的数据,并将其存储在一个合适的数据结构里以便后续操作。 - **时间轴离散化**:考虑到浮点数精度误差可能导致计算错误,应该把整个过程划分成若干个小的时间间隔来进行模拟仿真。 - **碰撞检测算法实现**:编写函数用来判定任意两个矩形之间是否存在重叠区域;当发现新的连接关系时更新可达性矩阵。 - **连通分量查找技术应用**:利用图论知识快速求解当前状态下哪些节点属于同一个集合内——即能否通过其他成员间接相连。 最后输出结果前记得考虑边界条件! ```cpp // 假设已经定义好了必要的类和辅助功能... bool canReachEnd(vector<Platform>& platforms, double endTime){ // 初始化工作... for(double currentTime = startTime; currentTime <= endTime ;currentTime += deltaT){ updatePositions(platforms, currentTime); buildAdjacencyMatrix(platforms); if(isConnected(startNode,endNode)){ return true; } } return false; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值