(2020.3.26)Codeforces Round #629 (Div. 3) 补题

CF1328A Divisibility Problem

输入a,b,求a自增的次数,使得最终的a满足a%b==0

第一反应:for循环直到满足条件为止,然后果不其然TLE。说实话A题都是很弱智的,第一反应往往都会T,稍微思考一下就可以了……

先判断(a \% b==0),再考虑详细情况:若(a>b)(a)要自增的次数就是(b-a\%b),若(a<b)

(a)要自增的次数就是(b-a),也就是(b-a\% b),两种情况可以统一。​

$color{green}{CF1328A-代码}$
#include <bits/stdc++.h>
using namespace std;
int main() {
    int t;
    cin >> t;
    while (t--) {
	int a, b;
	cin >> a >> b;
	if (a % b == 0) cout << 0 << endl;
	else cout << b - a % b << endl;
    }
    return 0;
}

CF1328B K-th Beautiful String

给定长度为n的字符串,其中有2个b,有n-2个a。将满足上述条件的字符串按字典序由小到大排列,输出第k个字符串

一开始想的是二进制,然后又位运算找1的个数……显然会T,随瞪着题面找规律,然后发现:由上到下,第二个b的位置选法有1、2、3、4……种,递增下来的。再接着发现第一个b的位置也可以由k确定。

$color{green}{CF1328B-代码}$
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;

int main() {
    int t;
    cin >> t;
    while (t--) {
	int n, k;
	cin >> n >> k;
	int i = 0;
	while (++i) {
            k -= i;
	    if (k <= 0) break;
        }
	int pos1 = i+1;
	int pos2 = pos1+k-1;

	for (int j = n;j >=1;j--) {
	    if (j == pos1) cout << "b";
    	    else if (j == pos2) cout << "b";
	    else cout << "a";
        }
        cout << endl;
    }
    return 0;
}

CF1328C Ternary XOR

称仅由(0、1、2)组成的数为三元数。给定(n)位三元数(x),求(n)位三元数(a)(b),使得对于数上的第(i)位,满足(x_i=(a_i+b_i)\%3)。要求(a)(b) 中的最大者尽可能小。 输入保证(x)的左边第一位为(2)

对于第(i)位数,有3种情况:

(x_i=0 Rightarrow a_i=0,b_i=0)

② $x_i=1 Rightarrow a_i=1,b_i=0 $ 或 (a_i=0,b_i=1)

(x_i=2 Rightarrow a_i=1,b_i=1)

不妨设(a>b),则当(x_i)第一次为1时,令(a_i=1,b_i=0),那么无论后面怎么填,必有(a>b),结合题目要求,令后续的所有(a_i=0),即可满足(a、b)中的最大者尽可能小。而后续的(b_i=x_i)

因此只要标记是否遍历到(x_i)第一次为(1)即可。

$color{green}{CF1328C-代码}$
#include<iostream>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std;
string x;

int main() 
{
    int t;
    cin >> t;
    while (t--) 
    {
    	int n;
	cin >> n;
	bool ok = true;
	cin >> x;
	for (int i = 0;i < n;i++) 
	{
    	    if (!ok) cout << "0";
    	    else if (x[i] == '1') { ok = false; cout << x[i]; }
            else if (x[i] == '2') cout << "1";
	    else if (x[i] == '0') cout << "0";
        }
	cout << endl;
	ok = true;
	for (int i = 0;i < n;i++) 
	{
    	    if (!ok) cout << x[i];
            else if (x[i] == '2') cout << "1";
            else if (x[i] == '0') cout << "0";
	    else if (x[i] == '1') { ok = false;cout << "0"; }
	}
	    cout << endl;
	}
    return 0;
}

有一环形数组,要求当两个相邻元素不同时,这两个元素要涂上不同的颜色。相邻元素相同时,颜色可以相同也可以不同。输出颜色种类最少的种类数目及涂色方案。

先考虑特殊情况:所有元素都相同。显然是1种颜色。

再考虑元素个数为偶数个的情况:如ABABABAB这样涂色一定满足条件。

最后考虑元素个数为奇数个的情况:一定会有一种颜色相邻并重复,如ABABABABB,其对应的颜色必须相同。故只要考虑数组中是否存在一对相邻元素相等即可,如果存在,涂2种颜色,且重复的颜色位置应与相邻且相等元素对应;如果不存在,涂3种颜色。

$color{green}{CF1328D-代码}$
#include<iostream>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std;

int a[200010];
int main() 
{
    int t;
    cin >> t;
    while (t--) {
        memset(a, 0, sizeof(a));
	int n,cnt=1;
	bool repeat=false;
	cin >> n;
	a[0] = -1000000;
	for (int i = 1;i <= n;i++) {
	    cin >> a[i];
	    if (a[i] == a[i - 1]) {
		repeat = true;
	        cnt++;
	    }
	}
	if (a[1] == a[n]) repeat = true;
	if (cnt == n) {
	    cout << "1" << endl;
	    for (int i = 1;i <= n;i++) cout << "1 ";
	}
	else if (n % 2 == 0) {
	    cout << "2" << endl;
	    for (int i = 1;i <= n;i++) {cout << (i % 2) + 1<<" ";}
        }
        else {
            if (repeat) {
	    cout << "2" << endl;
	    int r = 0;
	    for (int i = 1;i <= n;i++) {
		int p = i - 1;
	        if (p == 0) p = n;
		if (r) cout << (i % 2) + 1 << " ";
	        else if (a[i] == a[p]) {
	            cout << (i % 2) + 1 << " ";
	            r = 1;
		}
		else cout << 2-(i%2) << " ";
	    }
        }
        else {
            cout << "3" << endl;
	    for (int i = 1;i <= n - 1;i++) {cout << (i % 2) + 1 << " ";}
            cout << "3";
	}
    }
    cout << endl;
    }
    return 0;
}

CF1328E Tree Queries


CF1328F Make k Equal

原文地址:https://www.cnblogs.com/streamazure/p/12582568.html