首页 > 其他分享 >「解题报告」Codeforces Round 653 (Div. 3)

「解题报告」Codeforces Round 653 (Div. 3)

时间:2023-10-24 20:23:05浏览次数:42  
标签:ch read Codeforces Alice int while 653 Div Bob

A. Required Remainder

You are given three integers \(x, y\) and \(n\). Your task is to find the maximum integer \(k\) such that \(0 \le k \le n\) that \(k \bmod x = y\), where \(\bmod\) is modulo operation. Many programming languages use percent operator % to implement it.

In other words, with given \(x, y\) and \(n\) you need to find the maximum possible integer from \(0\) to \(n\) that has the remainder \(y\) modulo \(x\).

You have to answer \(t\) independent test cases. It is guaranteed that such \(k\) exists for each test case.

给你 \(x, y, n\),让你在 \(\left [0, n \right ]\) 中找到最大的 \(k\),值得 \(k\) 满足 \(k \bmod x = y\)。

先判断 \(n\) 是否满足,如果满足直接输出 \(n\),否则对余数 \(s\) 进行分类讨论,如果 \(s > y\),则 \(n\) 减去 \(s - y\),否则 \(n\) 减去 \(s - (x - y)\)。

// The code was written by yifan, and yifan is neutral!!!

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define bug puts("NOIP rp ++!");
#define rep(i, a, b, c) for (int i = (a); i <= (b); i += (c))
#define per(i, a, b, c) for (int i = (a); i >= (b); i -= (c))

template<typename T>
inline T read() {
    T x = 0;
    bool fg = 0;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        fg |= (ch == '-');
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = (x << 3) + (x << 1) + (ch ^ 48);
        ch = getchar();
    }
    return fg ? ~x + 1 : x;
}

template<typename T>
void write(T x) {
    if (x < 0) {
        putchar('-');
        x = -x;
    }
    if (x > 9) {
        write(x / 10);
    }
    putchar(x % 10 + '0');
}

template<typename T>
void print(T x, char c) {
   write(x);
   putchar(c);
}

int T, x, y, n;

void solve() {
    x = read<int>(), y = read<int>(), n = read<int>();
    int res = n % x;
    if (res == y) {
        print(n, '\n');
        return ;
    }
    if (res > y) {
        print(n - (res - y), '\n');
    } else {
        print(n - res - (x - y), '\n');
    }
}

int main() {
    T = read<int>();
    while (T --) {
        solve();
    }
    return 0;
}

B. Multiply by 2, divide by 6

You are given an integer \(n\). In one move, you can either multiply \(n\) by two or divide \(n\) by \(6\) (if it is divisible by \(6\) without the remainder).

Your task is to find the minimum number of moves needed to obtain \(1\) from \(n\) or determine if it's impossible to do that.

You have to answer \(t\) independent test cases.

给你一个数 \(n\),可以对 \(n\) 进行两种操作,让 \(n\) 乘上 \(2\),或者 \(n\) 除以 \(6\)(必须能整除时才可以),问最小需要多少步,可以让 \(n\) 变成 \(1\),或者确定 \(n\) 不可能变成 \(1\)。

\(n\) 想变成 \(1\),其质因数分解中只能有 \(2, 3\) 两种质数,不可以有其他质数,同时必须有分解出的 \(2\) 的个数小于等于 \(3\) 的个数(因为可以通过操作 \(1\) 乘上 \(2\))。
除以 \(6\) 使得 \(n\) 变为 \(1\),只需让因数中 \(2\) 的个数等于 \(3\) 的个数即可。

// The code was written by yifan, and yifan is neutral!!!

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define bug puts("NOIP rp ++!");
#define rep(i, a, b, c) for (int i = (a); i <= (b); i += (c))
#define per(i, a, b, c) for (int i = (a); i >= (b); i -= (c))

template<typename T>
inline T read() {
    T x = 0;
    bool fg = 0;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        fg |= (ch == '-');
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = (x << 3) + (x << 1) + (ch ^ 48);
        ch = getchar();
    }
    return fg ? ~x + 1 : x;
}

template<typename T>
void write(T x) {
    if (x < 0) {
        putchar('-');
        x = -x;
    }
    if (x > 9) {
        write(x / 10);
    }
    putchar(x % 10 + '0');
}

template<typename T>
void print(T x, char c) {
   write(x);
   putchar(c);
}

int T, n;

void solve() {
    n = read<int>();
    int tmp = n, cnt2 = 0, cnt3 = 0;
    while (tmp % 6 == 0) {
        tmp /= 6;
        ++ cnt2;
        ++ cnt3;
    }
    while (tmp % 3 == 0) {
        tmp /= 3;
        ++ cnt3;
    }
    while (tmp % 2 == 0) {
        tmp /= 2;
        ++ cnt2;
    }
    if (tmp != 1 || cnt3 < cnt2) {
        puts("-1");
        return ;
    }
    print(cnt3 - cnt2 + cnt3, '\n');
}

int main() {
    T = read<int>();
    while (T --) {
        solve();
    }
    return 0;
}

C. Move Brackets

You are given a bracket sequence \(s\) of length \(n\), where \(n\) is even (divisible by two). The string \(s\) consists of \(\frac{n}{2}\) opening brackets '(' and \(\frac{n}{2}\) closing brackets ')'.

In one move, you can choose exactly one bracket and move it to the beginning of the string or to the end of the string (i.e. you choose some index \(i\), remove the \(i\)-th character of \(s\) and insert it before or after all remaining characters of \(s\)).

Your task is to find the minimum number of moves required to obtain regular bracket sequence from \(s\). It can be proved that the answer always exists under the given constraints.

Recall what the regular bracket sequence is:

  • "()" is regular bracket sequence;
  • if \(s\) is regular bracket sequence then "(" + \(s\) + ")" is regular bracket sequence;
  • if \(s\) and \(t\) are regular bracket sequences then \(s\) + \(t\) is regular bracket sequence.

For example, "()()", "(())()", "(())" and "()" are regular bracket sequences, but ")(", "()(" and ")))" are not.

You have to answer \(t\) independent test cases.

给一个长度为 \(n\) 的括号字符串,你可以选择任意位置 \(i\),将 \(i\) 位置的字符移动到整个字符串最左边或最右边,问最小经过多少次操作才可以使得符合 () 类型。

找到有多少个 ) 没有匹配,这些没有匹配的 ) 个数就是最终答案。

// The code was written by yifan, and yifan is neutral!!!

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define bug puts("NOIP rp ++!");
#define rep(i, a, b, c) for (int i = (a); i <= (b); i += (c))
#define per(i, a, b, c) for (int i = (a); i >= (b); i -= (c))

template<typename T>
inline T read() {
    T x = 0;
    bool fg = 0;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        fg |= (ch == '-');
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = (x << 3) + (x << 1) + (ch ^ 48);
        ch = getchar();
    }
    return fg ? ~x + 1 : x;
}

template<typename T>
void write(T x) {
    if (x < 0) {
        putchar('-');
        x = -x;
    }
    if (x > 9) {
        write(x / 10);
    }
    putchar(x % 10 + '0');
}

template<typename T>
void print(T x, char c) {
   write(x);
   putchar(c);
}

const int N = 60;

int T, n;
string s;

void solve() {
    n = read<int>();
    cin >> s;
    int cnt = 0, ans = 0;
    for (char c : s) {
        if (c == '(') {
            ++ cnt;
        } else {
            if (!cnt) {
                ++ ans;
            } else {
                -- cnt;
            }
        }
    }
    print(ans, '\n');
}

int main() {
    T = read<int>();
    while (T --) {
        solve();
    }
    return 0;
}

D. Zero Remainder Array

You are given an array \(a\) consisting of \(n\) positive integers.

Initially, you have an integer \(x = 0\). During one move, you can do one of the following two operations:

  1. Choose exactly one \(i\) from \(1\) to \(n\) and increase \(a_i\) by \(x\) (\(a_i := a_i + x\)), then increase \(x\) by \(1\) (\(x := x + 1\)).
  2. Just increase \(x\) by \(1\) (\(x := x + 1\)).

The first operation can be applied no more than once to each \(i\) from \(1\) to \(n\).

Your task is to find the minimum number of moves required to obtain such an array that each its element is divisible by \(k\) (the value \(k\) is given).

You have to answer \(t\) independent test cases.

给定有 \(n\) 个元素的数组 \(a\) 和一个整数 \(k\),初始元素都是 \(0\),有一个整数 \(x = 0\),可以进行两个操作,任选一个位置 \(i\),使得 \(a_i = a_i + x\),同时 \(x = x + 1\);或者直接 \(x = x + 1\),问通过最小多少次操作可以使得 \(a\) 数组中的元素都能被 \(k\) 整除。

将每一个元素与 \(k\) 的倍数的差都求出来,只要有相等的,就给其中一个加 \(k\),最后求出最大值。

// The code was written by yifan, and yifan is neutral!!!

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define bug puts("NOIP rp ++!");
#define rep(i, a, b, c) for (int i = (a); i <= (b); i += (c))
#define per(i, a, b, c) for (int i = (a); i >= (b); i -= (c))

template<typename T>
inline T read() {
    T x = 0;
    bool fg = 0;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        fg |= (ch == '-');
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = (x << 3) + (x << 1) + (ch ^ 48);
        ch = getchar();
    }
    return fg ? ~x + 1 : x;
}

template<typename T>
void write(T x) {
    if (x < 0) {
        putchar('-');
        x = -x;
    }
    if (x > 9) {
        write(x / 10);
    }
    putchar(x % 10 + '0');
}

template<typename T>
void print(T x, char c) {
   write(x);
   putchar(c);
}

const int N = 2e5 + 5;

int T, n, k;
int a[N];
ll cha[N], cnt[N];

void solve() {
    n = read<int>(), k = read<int>();
    int g;
    rep (i, 1, n, 1) {
        a[i] = read<int>();
        g = a[i] / k;
        if (g * k < a[i]) {
            cha[i] = (g + 1) * k - a[i];
        } else {
            cha[i] = 0;
        }
        cnt[i] = 0;
    }
    sort(cha + 1, cha + n + 1);
    rep (i, 2, n, 1) {
        if (cha[i] && cha[i] == cha[i - 1]) {
            cnt[i] = cnt[i - 1] + 1;
        }
    }
    ll maxx = 0;
    rep (i, 1, n, 1) {
        cha[i] += cnt[i] * k;
        maxx = max(maxx, cha[i]);
    }
    if (maxx == 0) {
        print(maxx, '\n');
    } else {
        print(maxx + 1, '\n');
    }
}

int main() {
    T = read<int>();
    while (T --) {
        solve();
    }
    return 0;
}

E1. Reading Books (easy version)

Easy and hard versions are actually different problems, so read statements of both problems completely and carefully.

Summer vacation has started so Alice and Bob want to play and joy, but... Their mom doesn't think so. She says that they have to read some amount of books before all entertainments. Alice and Bob will read each book together to end this exercise faster.

There are \(n\) books in the family library. The \(i\)-th book is described by three integers: \(t_i\) — the amount of time Alice and Bob need to spend to read it, \(a_i\) (equals \(1\) if Alice likes the \(i\)-th book and \(0\) if not), and \(b_i\) (equals \(1\) if Bob likes the \(i\)-th book and \(0\) if not).

So they need to choose some books from the given \(n\) books in such a way that:

  • Alice likes at least \(k\) books from the chosen set and Bob likes at least \(k\) books from the chosen set;
  • the total reading time of these books is minimized (they are children and want to play and joy as soon a possible).

The set they choose is the same for both Alice an Bob (it's shared between them) and they read all books together, so the total reading time is the sum of \(t_i\) over all books that are in the chosen set.

Your task is to help them and find any suitable set of books or determine that it is impossible to find such a set.

Alice 和 Bob 一共有 \(n\) 本书要读。第 \(i\) 本书有三个属性:阅读时间 \(t_i,a_i\)(为 \(1\) 表示 Alice 喜欢这本书,为 \(0\) 表示 Alice 不喜欢),\(b_i\)(为 \(1\) 表示 Bob 喜欢这本书,为 \(0\) 表示 Bob 不喜欢)。

他们需要从这些书中选择若干本,满足

  • 这些书中至少有 \(k\) 本是 Alice 喜欢的,至少有 \(k\) 本是 Bob 喜欢的。
  • 阅读的总时间最小(总时间为选中的书的 \(t_i\) 的总和)

设 \(A\) 是 Alice 喜欢但 Bob 不喜欢的书,\(B\) 是 Alice 不喜欢但 Bob 喜欢的书,\(C\) 是 Alice 和 Bob 都喜欢的书。将 \(A\) 和 \(B\) 从小到大排个序,然后两两组合放入 \(D\) 中,最后从 \(C\) 和 \(D\) 中一共选出 \(k\) 个,使得费用最小。

在此贴上 grz 的代码。%%% grz 自己懒得写了,

/*XH_ccs*/
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
inline int read()
{
	int f=1,w=0;char ch=getchar();
	while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){w=w*10+ch-48;ch=getchar();}
	return f*w;
}
int n,k,ans,suma,sumb,cnta,cntb,cntc,A[N],B[N],C[N];

int main()
{
	n=read();
	k=read();
	for (int i=1;i<=n;i++)
	{
		int t=read();
		int a=read();
		int b=read();
		if(a && !b)
			A[++cnta]=t;
		if(!a && b)
			B[++cntb]=t;
		if(a && b)
			C[++cntc]=t;
		suma+=a;
		sumb+=b;
	}
	if(suma<k || sumb<k)
	{
		cout<<-1;
		exit(0);
	}
	sort(A+1,A+1+cnta);
	sort(B+1,B+1+cntb);
	int len=min(cnta,cntb);
	for (int i=1;i<=len;i++)
		C[++cntc]=A[i]+B[i];
	sort(C+1,C+1+cntc);
	for (int i=1;i<=k;i++)
		ans+=C[i];
	cout<<ans;
	return 0;
}

标签:ch,read,Codeforces,Alice,int,while,653,Div,Bob
From: https://www.cnblogs.com/yifan0305/p/17785672.html

相关文章

  • Codeforces Round 905 (Div. 2)
    Preface周日晚上Div1,2,3同乐,但我不想打Div1,同时第三个号由于只打了两场没够到Div2的门槛,因此刚好打不了Div2,遂玩了一晚上LOL今天补了下这场题感觉难度偏低,E之前的题都比较签,F刚开始没想到转化成差分最小准备去写扫描线+线段树了,后面发现其实可以写的很简单A.Chemistry签,设......
  • CodeForces 946F Fibonacci String Subsequences
    洛谷传送门CF传送门duel的时候差点不会2400了。套路地,考虑每个\(F(x)\)中与\(s\)相同的子序列的贡献。设这个子序列为\(F(x)_{p_1},F(x)_{p_2},F(x)_{p_3},\ldots,F(x)_{p_n}\)。我们想要它成为一个子序列的子串,那么\(F(x)_{[p_1,p_n]}\)中除了\(p_1\simp_......
  • Codeforces 1862G 题解
    传送门题解因为有这个操作:将序列\(a\)加上\(\{n,n-1,\cdots,1\}\),考虑差分。那么显然每次操作会将差分数组中的每个元素减去\(1\),如果差分数组中有\(0\),就会把\(0\)删除。所以可以发现差分数组中剩下的一定是操作前的最大值。由于操作后最大值还是最大值,最小值仍......
  • Codeforces Round 886 (Div. 4) 题解
    link我为什么还要vpdiv4场。。。A直接找最大的两个判断一下。voidsolve(){ inta[3]; cin>>a[0]>>a[1]>>a[2]; sort(a,a+3); if(a[2]+a[1]>=10)cout<<"YES\n"; elsecout<<"NO\n";}B按照题目意思模拟。voidsolv......
  • Codeforces Round#905 解题报告
    由于是解题报告不是过题报告,所以理所当然的放弃了后三题代码的写。感觉这场Div1D是cyh的菜,E是gjk的菜。我负责菜。只写Div1题的题解。A双指针可以做\(m=1\)你发现随便换\(a_1\)答案最多减少\(1\),而且\(a_1\)越趋向于减少,所以可以二分分割点B最短路,怎么dij......
  • Codeforces Round 905 (Div. 2) D1. Dances (Easy version)(贪心+二分)
    CodeforcesRound905(Div.2)D1.Dances(Easyversion)思路:对于\(a\),它的头默认为\(1\),则\(a_0\)=\(1\)对于排完序的\(a\)与\(b\)数组最优为从\(a\)的结尾删除,从\(b\)的开头删除二分保留位数,删去\(n-mid\)位,即\(a\)从\(0\)开始,\(b\)从\(k\)(\(k=n-......
  • 「解题报告」Codeforces Round 905 (Div. 3)
    A.MorningYouaregivenafour-digitpincodeconsistingofdigitsfrom\(0\)to\(9\)thatneedstobeentered.Initially,thecursorpointstothedigit\(1\).Inonesecond,youcanperformexactlyoneofthefollowingtwoactions:Pressthecu......
  • Codeforces Round 905 (Div. 2) C. You Are So Beautiful(数据结构)
    CodeforcesRound905(Div.2)C.YouAreSoBeautiful定义:设数组abcd子数组定义:从原数组砍去前面若干元素,后边若干元素,剩余的数组。如:bc、ab子序列定义:从原数组删除若干元素,剩余元素拼凑一起,组成的数组。如:ac、bd思路:作为结果的连续子数组,如果他为[\(a_l\),……,\(a_......
  • Educational Codeforces Round 144(CF1796 D~E) 题解
    D.MaximumSubarray题目链接十分钟秒了一道*2000,非常爽,但是个人感觉确实非常简单。下面令\(b_i=a_{i}-x\),\(b_i'=a_i+x\)。因为\(k<=20\),因此考虑一个复杂度与\(k\)相关的做法。不妨dp:设\(f_{i,j,0/1}\)表示考虑了前\(i\)个数,对\(j\)个数加上了\(x\),第\(i\)......
  • Codeforces Round 905 (Div. 2)
    目录写在前面ABCD1/D2E写在最后写在前面比赛地址:https://codeforces.com/contest/1884oonp这场div2怎么才2k5人打啊我草里面还不知道多少大神的小号,呃呃打了1k3掉了75分也是牛逼A考虑如何拼出一个长度为\(n-k\)的回文串,先一对一对地拼,再看需不需要再顶上去一个......