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;
}
CF1328D Carousel
有一环形数组,要求当两个相邻元素不同时,这两个元素要涂上不同的颜色。相邻元素相同时,颜色可以相同也可以不同。输出颜色种类最少的种类数目及涂色方案。
先考虑特殊情况:所有元素都相同。显然是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;
}