Codeforces Round #629 (Div. 3)

A Divisibility Problem

题意

给你两个正整数\(a,b\) 你每次可以执行一次\(a++\)操作,问你最小的操作步数,使得\(a\)能被\(b\)整除

思路

数学

分情况讨论

当\(a<b\) 时,显然只有\(a == b\)时才能保证\(a\)被\(b\)整除

当\(a>b\) 时,只要把\(a\)调整到离\(kb\)最近的一个\(b\)的倍数,即\(\lceil {a / b}\rceil * b - a\)

#include <bits/stdc++.h>
using namespace std;
#define endl ‘\n‘
#define IO ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
typedef long long LL;
typedef double db;
typedef pair<int,int> PII;
const int N = 1e5 + 10;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const db EXP = 1e-9;
int main() {
    IO;
    int t,a,b;
    cin >> t;
    while(t --) {
        int cnt = 0;
        cin >> a >> b;
        if(a < b) cnt += (b - a);
        else cnt += ((a + b - 1)/ b) * b - a;
        cout << cnt << endl;
    }
    return 0;
}

B K-th Beautiful String

题意

给定一个\(n>2\)和\(k\),初始化字符串的前\(n-2\)个字符为\(a\),最后两个字符为\(b\),此为字符串的第一个排列,所有字符串的按字典序排列,让你求第\(k\)个字符串

思路

二进制,双指针,贪心

把\(a\)看成\(0\),\(b\)看成\(1\),整个字符串的排列就是一个二进制加法

每次,排列的名次\(+1\),整个字符串就加上它的\(lowbit()\),为了保证整个字符串只有两个\(b\)

如果lowbit发生了进位,就要在末尾再加上一个\(1\)

具体做法不能直接按二进制加法来,因为题目的数据范围是\(1e5\),\(int,long long\)等数据类型都达不到这么长的数据位,所以考虑维护两个指针\(i,j\) 分别表示第一个\(b\)的位置和第二个\(b\)的位置

如果\(i+1==j\)说明\(i,j\)相邻,那么他们相加必然导致进位,所以\(i++,j=n\),

如果\(i,j\)不相邻,每次只需要处理\(j\)的进位即可,\(j++\)

循环\(k\)次,\(i,j\)的位置即是两个\(b\)的位

#include <bits/stdc++.h>
using namespace std;
#define endl ‘\n‘
#define IO ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
typedef long long LL;
typedef double db;
typedef pair<int,int> PII;
const int N = 1e5 + 10;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const db EXP = 1e-9;
int main() {
    IO;
    int t,n,k;
    cin >> t;
    while(t --) {
        cin >> n >> k;
        int i = n - 1,j = n;// b is here;
        k --;
        while(k --) {
            if(i + 1 == j) {
                i --;
                j = n;
            }
            else {
                j --;
            }
        }
        for(int k = 1;k <= n; ++k) {
            if(k == i || k == j) cout << ‘b‘;
            else cout << ‘a‘;
        }
        cout << endl;
    }
    return 0;
}

C Ternary XOR

题意

给定一个三进制的数\(c\),定义运算符\(⊙\) 表示\(c_i=(a_i+b_i)\mod3\)

让你求另外两个三进制数\(a,b\),使得\(c=a⊙b\),且\(max(a,b)\)最小

思路

贪心

因为它的运算不涉及进位,只对当前位有影响,所以只考虑当前位即可

对于\(c_i\)的每一位,先尽量保持均分到\(a_i,b_i\)

如果某一位在过程中发生了\(0,1\)分配,那么接下来的所有数字都分配到\(0\)那一位后面即可

这样就能使得\(a,b\)尽可能相近了。

#include <bits/stdc++.h>
using namespace std;
#define endl ‘\n‘
#define IO ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
typedef long long LL;
typedef double db;
typedef pair<int,int> PII;
const int N = 5e4 + 10;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const db EXP = 1e-9;
int a[N],c[N],b[N];
int main() {
    IO;
    int t,n;
    char x;
    cin >> t;
    while(t --) {
        memset(b,0,sizeof b);
        memset(c,0,sizeof c);
        cin >> n;
        for(int i = 0;i < n; ++i) {
            cin >> x;
            a[i] = x - ‘0‘;
        }
        b[0] = c[0] = 1;
        int f = 0;
        for(int i = 1;i < n; ++i) {
            if(a[i] == 1 && !f) {
                if(b[i - 1] && !c[i - 1]) c[i] = 1;
                else if(!b[i - 1] && c[i - 1]) b[i] = 1;
                else b[i] = 1,f = 1;
            }
            else if(a[i] == 2 && !f) {
                if(b[i - 1] && !c[i - 1]) c[i] = 2;
                else if(!b[i - 1] && c[i - 1]) b[i] = 2;
                else {
                    b[i] = 1;
                    c[i] = 1;
                }
            }
            else if(f) {
                for(int j = i;j < n; ++j) {
                    c[j] = a[j];
                }
                break;
            }
        }
        for(int i = 0;i < n; ++i) cout << b[i];
        cout << endl;
        for(int i = 0;i < n; ++i) cout << c[i];
        cout << endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/lukelmouse/p/12579396.html

时间: 2024-07-30 16:42:28

Codeforces Round #629 (Div. 3)的相关文章

Codeforces Round #629 (Div. 3) D. Carousel(思维/贪心?)

The round carousel consists of nn figures of animals. Figures are numbered from 11 to nn in order of the carousel moving. Thus, after the nn -th figure the figure with the number 11 follows. Each figure has its own type — the type of the animal corre

Make k Equal from Codeforces Round #629 (Div. 3)

description you are given an array and you are asked to make \(k\) elements of it equal after some operations. you can make one of the following operations: take one of the minimum and increase its value by \(1\) take one of the maximum and subtract

Codeforces Round #629 (Div. 3) E. Tree Queries(lca题)

https://codeforces.com/contest/1328/problem/E E. Tree Queries You are given a rooted tree consisting of nn vertices numbered from 11 to nn. The root of the tree is a vertex number 11. A tree is a connected undirected graph with n−1n−1 edges. You are

Codeforces Round #629 (Div. 3) F - Make k Equal (离散化 树状数组维护前缀和)

https://codeforces.com/contest/1328/problem/F 首先把a数组处理成pair对(num,cnt),表示数字num有cnt个,然后按num升序排序离散化一下. 对于一个数x,若想使得小于x的数字都变成x,必须先把所有小于x的数变成x-1,然后再+1变成x. 同理,要使得大于x的数变成x,必须把所有大于x的数字变成x+1,然后再-1变成x. 以上是题意所要求的必须操作. 思路: 1. 用f[i]数组记录离散化后前i大的数字的总数,那么对于任意第i大数字,可以

Codeforces Round #629 (Div. 3) E. Tree Queries(LCA)

https://codeforces.com/contest/1328/problem/E 题目所描述的是一棵树,题中已明示1为root结点. 题目可以转化为,是否存在一条路径,满足集合中的k个点到路径的距离小于等于1? 思路: 1.首先倍增离线预处理出结点深度,便于后续在线询问LCA 2.对于每次的询问,依次扫描k个点.对于集合中的u和v两点,每次我们求出u和v的LCA,计算u和v到LCA的距离,如果u和v到LCA的距离同时大于1,那么说明无法找到一条路径,使得u和v到该路径链的距离小于等于1

D. Carousel.(简单做法)Codeforces.Round #629 (Div. 3)

题目大意 给一个数组,入伙前后两个元素值不同则必须让他们染不同的颜色,问你如何染色能使得使用的颜色种类最少 做法 用贪心的思路,从前往后扫一遍数组按照题目中的规则,如果与前一个元素相同就染同样的颜色,不同就染不一样的,但是只染1,2两种颜色. 由于是个环,最后只需要判断一下最后一个元素是不是和第一个元素不同的情况下染了相同的颜色,如果是,就看数组中有没有染了相同的颜色还挨在一起,如果有,把后面一个元素的颜色换成与前一个元素不同的,并且后面所有的元素都换成与原来相反的 x%2+1 :正常输出即可.

Codeforces Round #629 (Div. 3) 解题报告

A [题意]签到题 B [题意]长度为n的字符串,由n-2个a和2个b组成,按照字典序排序,问第k个 [题解]读题细心,最开始以为是ab代表01,搞二进制转化,实际上上面是正确题意,直接算b的位置即可 C [题意]长度为n的由0,1,2组成的序列,分成两个数字,让他们的最小值最大 [题解]所以我们只需要让他尽量平均分即可,0可以分成0和0,2可以分成1和1,所以我们只有当碰到1的时候开始特殊处理,所以我们把1给一个数,然后下来所有的1和2都分配给另外一个数,以此能够保证分配的平均 D [题意]给

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i

Codeforces Round #424 (Div. 2) D. Office Keys(dp)

题目链接:Codeforces Round #424 (Div. 2) D. Office Keys 题意: 在一条轴上有n个人,和m个钥匙,门在s位置. 现在每个人走单位距离需要单位时间. 每个钥匙只能被一个人拿. 求全部的人拿到钥匙并且走到门的最短时间. 题解: 显然没有交叉的情况,因为如果交叉的话可能不是最优解. 然后考虑dp[i][j]表示第i个人拿了第j把钥匙,然后 dp[i][j]=max(val(i,j),min(dp[i-1][i-1~j]))   val(i,j)表示第i个人拿