Codeforces Round #615 (Div. 3)

暂时没有F题的题解。太菜了。

A - Collecting Coins

题意:有三个人,分别有a,b,c枚硬币,你有n枚硬币,要求把n枚硬币全部给这三个人并且使得他们的硬币数变为相等。问是否可行。

题解:先验证硬币总数a+b+c+n是否能被3整除,然后验证要补的硬币的数量少于n。

void test_case() {
    int a[5], n;
    scanf("%d%d%d%d", &a[1], &a[2], &a[3], &n);
    sort(a + 1, a + 1 + 3);
    int sum = a[3] - a[1] + a[3] - a[2];
    if(sum > n || (sum - n) % 3 != 0)
        puts("NO");
    else
        puts("YES");
}

B - Collecting Packages

题意:有个机器人,只能向上走或者向右走,要从(0,0)经过所有的点(xi,yi),求是否可行,若可行则输出字典序最小的方案。

题解:字典序最小就是说先往右走再往上走。直接把所有点按x排序,要求每个点与(0,0)包围的矩形包含此前的所有点,只需要比前面的点都高就行了。由数学归纳法可知只需要比前一个点高就行了。

int n;
pii p[1005];

void test_case() {
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i) {
        int x, y;
        scanf("%d%d", &x, &y);
        p[i] = {x, y};
    }
    sort(p + 1, p + 1 + n);
    for(int i = 2; i <= n; ++i) {
        if(p[i].second < p[i - 1].second) {
            puts("NO");
            return;
        }
    }
    puts("YES");
    int cx = 0, cy = 0;
    for(int i = 1; i <= n; ++i) {
        while(cx < p[i].first) {
            putchar('R');
            ++cx;
        }
        while(cy < p[i].second) {
            putchar('U');
            ++cy;
        }
    }
    putchar('\n');
}

C - Product of Three Numbers

题意:给一个数n,满足n>=2,要求将n分解成互异的三个数a,b,c,使得a*b*c==n,且a,b,c>=2。给出一种分解的方案,或者说明其不存在。

题解:一开始没看见>=2直接判断质数就上了(虽然这样也不对,比如9不能分解为1,3,3),仔细一想跟质数的种类有关系,所以可以直接分解质因数。假如有3种以上的质因数,那么前两个数要两种,剩下的最后一个数补位就是一种字典序最小的构造。假如只有1种质因数,那么肯定至少需要6次,前两个数分别要1次和2次,剩下的至少要3次,这也是一种字典序最小的构造。假如有2种质因数,那么总次数<=3的显然是无解的,而总次数>=4的必定有解。首先把两种质因数各1次拿出来,那么剩下的那个2次也不会和前面的重复,只是这样并不是字典序最小(还好题目没要求)。

最简单的思路也是字典序最小的思路就是直接暴力枚举a和b。

下面这个质因数分解的模板貌似还带有筛出最小质因子的功能的。

const int MAXN = 1e5;
int p[MAXN + 5], ptop;
int pn[MAXN + 5];

void sieve() {
    int n = MAXN;
    pn[1] = 1;
    for(int i = 2; i <= n; i++) {
        if(!pn[i])
            p[++ptop] = i;
        for(int j = 1; j <= ptop; j++) {
            int t = i * p[j];
            if(t > n)
                break;
            pn[t] = p[j];
            if(i % p[j] == 0)
                break;
        }
    }
}

int fac[105][2], ftop;

void get_fac(int n) {
    ftop = 0;
    for(int i = 1; i <= ptop; ++i) {
        if(n % p[i] == 0) {
            fac[++ftop][0] = p[i];
            fac[ftop][1] = 0;
            while(n % p[i] == 0) {
                n /= p[i];
                ++fac[ftop][1];
            }
        }
    }
    if(n > 1) {
        fac[++ftop][0] = n;
        fac[ftop][1] = 1;
    }
}

void test_case() {
    int n;
    scanf("%d", &n);
    get_fac(n);
    if(ftop >= 3) {
        puts("YES");
        printf("%d %d %d\n", fac[1][0], fac[2][0], n / fac[1][0] / fac[2][0]);
        return;
    } else if(ftop == 1) {
        if(fac[1][1] >= 6) {
            puts("YES");
            printf("%d %d %d\n", fac[1][0], fac[1][0]*fac[1][0], n / fac[1][0] / fac[1][0] / fac[1][0]);
            return;
        } else {
            puts("NO");
            return;
        }
    } else {
        int sum = fac[1][1] + fac[2][1];
        if(sum <= 3) {
            puts("NO");
            return;
        } else {
            puts("YES");
            printf("%d %d %d\n", fac[1][0], fac[2][0], n / fac[1][0] / fac[2][0]);
            return;
        }
    }
}

D - MEX maximizing

题意:有q次操作和一个固定的正整数x,每次操作会往序列中加入一个数字y,你可以在任何时候对序列中的某个y进行任意多次加减x操作(但不能使他们变成负数),求使得整个序列的MEX最大的方案时的MEX的值。

题解:显然模x余数相同的都是同一种等价的东西,可以维护模x值不同结果的cnt。那么MEX操作就相当于询问整个cnt序列中的最小值(这个最小值是一层一层循环叠在下面把MEX垫高),然后再求序列中等于这个最小值的最左边的元素,这个显然可以用线段树来维护(甚至可以支持修改删除)。

但是最简单的操作还是在cnt里面数了之后不断尝试越过MEX即可。

E - Obtain a Permutation

题意:给一个n*m的矩阵,要求复原成形如:

1  2  3  4
5  6  7  8
9  10 11 12

的样子,也就是依次填充。

有两种cost都是1的操作,1种是直接修改某位置的数字,另一种是把一列向上轮换。

原文地址:https://www.cnblogs.com/KisekiPurin2019/p/12230102.html

时间: 2024-08-30 15:29:48

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

Codeforces Round #615 (Div. 3). D - MEX maximizing

题面:https://codeforces.com/contest/1294/problem/D 题目大意: 每次都会往你的数列里加一个值,你可以任意加减这个值若干次(但是只能加x或者减x) 然后问最小的不属于这个数列的非负整数是什么 你需要进行的操作是,让这个最小的不属于这个数列的非负整数最大 每次加一个值并且询问一遍 解题思路: 易得到,每一次输出的答案在进行完题目的贪心后会呈现上升趋势,且值最大只可能为序列内元素的个数 所以我们可以让每次加入的值在进行完若干次操作后尽量成为靠前的序列中还没

Codeforces Round #615 (Div. 3). B - Collecting Packages

题面:https://codeforces.com/contest/1294/problem/B 题目大意: 机器人从(0,0)开始,他只能往上'U'或者往右'R'走 坐标系中有着很多包裹,分别在一些点上 机器人需要走过去把这些包裹全部收集起来 问能不能做到 如果能,再输出移动方式,相同移动方式输出字典序最小的方案 解题思路: pair或者结构体排序,x与y的优先级任意,因为下一个包裹必定在当前机器人位置右方/上方/右上方 否则直接输出NO,表示不可能存在这种移动方式 在输出移动方式时,注意能先

Codeforces Round #615 (Div. 3) A-F简要题解

contest链接:https://codeforces.com/contest/1294 A. 给出a.b.c三个数,从n中分配给a.b.c,问能否使得a = b = c.计算a,b,c三个数的差值之和,n对其取余,判断是否为0即可. AC代码: 1 #include<iostream> 2 #include<vector> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstring>

Codeforces Round #615 (Div. 3) F. Three Paths on a Tree

F. Three Paths on a Tree 原题链接:https://codeforces.com/contest/1294/problem/F 题目大意: 给定一棵树,选出三点,使三点连成的j简单路径最大.简而言之,三个点连成的边的集合大小. 解题思路: 假设任取一点为三点连线的公共点,最长路径就是这个点到其他三个点的三条最长边之和,可知这个点一定在直径上(画图分析假设不在时的最长路径可反证).所以先求出树的直径,在使用$ans =(a b+a c+b c) / 2$遍历可以得到第三个点

Codeforces Round #615 (Div. 3) E. Obtain a Permutation

E. Obtain a Permutation 原题链接:https://codeforces.com/contest/1294/problem/E 题目大意: 给一个无序矩阵,可以进行两个操作: 1.改变任何元素的大小: 2.将任何一列中的元素向上提一位,也就是$a_{1, j}:=a_{2, j}, a_{2, j}:=a_{3, j}, \dots, a_{n, j}:=a_{1, j}$ 使得最后的矩阵变为有序的序列,即$\left.a_{1,1}=1, a_{1,2}=2, \ldot

题解 Codeforces Round #615 (Div. 3) (CF1294)

A:判断一下和是不是3的倍数,由于只加不减,所以还要判断有没有大于和的1/3. 1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #define it register int 5 #define ct const int 6 #define il inline 7 using namespace std; 8 int T,a,b,c,n,x; 9 namespace io{ 10 il c

Codeforces Round #615 (Div. 3) 题解

A - Collecting Coins 题意: 给你四个数a,b,c,d,n.问你是否能将n拆成三个数A,B,C,使得A+a=B+b=C+c. 思路: 先计算三个数的差值的绝对值abs,如果abs大于n则肯定不行,如果小于n,还需判断(n-abs)%3是否为0,不为0则不行. #include<iostream> #include<algorithm> #include<cmath> #include<cstring> #include<vector

Codeforces Round #615(div.3) A 题解

题意: 分别有a,b,c个硬币在对应的三个人手中,我有n个硬币,问如何将这n个硬币分给这三个人使得最后三个人的硬币数相同. 思路: 先求出每个人与最多的人的硬币个数的差距,然后拿n个硬币去填补这个空缺,分过剩下来没有分的如果可以%3==0,则说明可以相同.如果不为0则说明无法分配. 水题一道: #include<iostream> #include<algorithm> using namespace std; int main() { int t; cin>>t; w

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

Codeforces Round #615(Div.3)解题报告 A. Collecting Coins 注意\(n\)可能不够用的情况. #include<bits/stdc++.h> using namespace std; typedef long long ll; int a, b, c, n; void solve() { cin >> a >> b >> c >> n; int mx = max(max(a, b), c); int