Codeforces Round #739 (Div. 3)(补题)
Posted 佐鼬Jun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #739 (Div. 3)(补题)相关的知识,希望对你有一定的参考价值。
D. Make a Power of Two
题意: 对于给定的一个数,有两种操作,可以选择任意位置删除这个数,也可以在数的右边加一个数,问操作至少几次,可以使这个数变成2的证次幂
思路: 直接提前预处理出来所有的2的整次幂的数,然后用当前数与所有2的证次幂的所有数进行比较,判断操作次数,最后取最小值。
当前数与2的整次幂的数的比较,就利用双指针就可以判断,拿着输入的
s
s
s串,与模式串进行匹配,因为s串是通过删除,右边添加的操作,可以直接利用双指针看有几对一样的,剩下都不是一样的
#include <bits/stdc++.h>
using namespace std;
#define ll long long
string s;
string str[100];
int solve(string b, string a) {
int j = 0;
int lena = a.size(), lenb = b.size();
for (int i = 0; i < lena; i++) {
if (j == lenb) {
break;
}
if (a[i] == b[j]) {
j++;
}
}
return lena + lenb - 2 * j;
}
int main() {
ll now = 1;
for (int i = 0; i <= 60; i++) {
str[i] = to_string(now << i);
}
int t;
cin >> t;
while (t--) {
cin >> s;
int res = 100;
for (int i = 0; i <= 60; i++) {
res = min(res, solve(str[i], s));
}
cout << res << endl;
}
}
E. Polycarp and String Transformation
题意: 给定一个字符串
s
s
s,和一个空串
t
t
t,
t
=
t
+
s
t=t+s
t=t+s,然后再选定
s
s
s串中的一个字母,使得
s
s
s串中所有的这个字母都删去,在
t
=
t
+
s
t=t+s
t=t+s,反复上述操作,知道
s
s
s串为空,现在给你
t
t
t串,让你输出
s
s
s串和删除字母的顺序
思路: 先根据
s
s
s字符串里的每个字母最后出现的位置,判断删除字母的顺序。再存每个字母在几个阶段出现。然后在每次读入字符是,也要读入它们的阶段数,即阶段数乘上这个字母的数量,现在长度和
s
s
s串是否相同,不相同就-1,相同再模拟一遍题目的要求,我们根据之前记录的字母删除顺序,构造出一个字符串,看最后构造出来的是否与
s
s
s串相同。
#include <bits/stdc++.h>
using namespace std;
string s;
vector<int> a;
bool b[30];
int pos[30];
int main() {
int t;
scanf("%d", &t);
while (t--) {
a.clear();
memset(b, 0, sizeof(b));
memset(pos, 0, sizeof(pos));
cin >> s;
for (int i = s.size() - 1; i >= 0; i--) {
if (!b[s[i] - 'a']) {
b[s[i] - 'a'] = 1;
a.push_back(s[i]);
}
}
for (int i = 0; i < a.size(); i++) {
pos[a[i] - 'a'] = a.size() - i;
}
int now = 0;
string res;
bool flag = 0;
for (int i = 0; i < s.size(); i++) {
res += s[i];
now += pos[s[i] - 'a'];
if (now > s.size()) break;
if (now == s.size()) {
string q, dex = res;
for (int i = a.size() - 1; i >= 0; i--) {
q += dex;
string dey;
for (int k = 0; k < dex.size(); k++) {
if (dex[k] != a[i]) {
dey += dex[k];
}
}
dex = dey;
}
if (q == s) {
flag = 1;
break;
}
}
}
if (!flag)
puts("-1");
else {
cout << res << " ";
for (int i = a.size() - 1; i >= 0; i--) {
printf("%c", a[i]);
}
cout << '\\n';
}
}
return 0;
}
F2. Nearest Beautiful Number (hard version)(和F1一样的)
题意: 一个数中,有至多
k
k
k个数字不同,这个数字就是
k
k
k美丽数字,现在让你给你一个数
n
n
n,让你输出
x
x
x
(
x
>
=
n
)
(x>=n)
(x>=n),
x
x
x是符合题意的最小的
k
k
k美丽数
思路: 从后往前枚举每个数,因为从后往前,每个数对这个数本身的权重是越来越大的,然后改当前这个枚举这位的数字,枚举肯定要枚举比它大的,例如
123
123
123,枚举第三位的时候,要从4到9枚举,因为
x
>
=
n
x>=n
x>=n,枚举第二位的时候,要从
3
3
3到9,如果枚举到当前位置的时候,不同数字的个数大于要求
K
K
K,那就再枚举别的数。如果符合题意,那就输出答案,输出的时候,如果不同的数字个数小于K,那就在后面一直加0即可,加到长度恰好为止,如果不同数字个数等于K,那就再在后面一直加出现数字最小的那个就行,不可能大于,大于就不输出了。
#include <bits/stdc++.h>
using namespace std;
int t, n, k;
bool check(int x, int c) {
vector<int> A(10);
while (x) {
A[x % 10] = 1;
x /= 10;
}
int cnt = 0;
for (auto x : A) {
cnt += x;
}
return cnt <= k;
}
int get(int x, int c) {
int u = x;
vector<bool> A(10);
while (x) {
A[x % 10] = 1;
x /= 10;
}
int cnt = 0;
for (auto x : A) {
cnt += x;
}
if (cnt == k) {
int y = 0;
for (int i = 9; i >= 0; i--) {
if (A[i]) {
y = i;
}
}
while (c--) u = u * 10 + y;
return u;
}
while (c--) u = u * 10;
return u;
}
int main() {
cin >> t;
while (t--) {
scanf("%d%d", &n, &k);
int N = n;
bool flag = 0;
for (int i = 0; i < 10 && !flag; i++, n /= 10) {
int g = n % 10;
if (i != 0) ++g;
for (int j = g; j < 10 && !flag; j++) {
if (check(n / 10 * 10 + j, i)) {
flag = 1;
printf("%d\\n", get(n / 10 * 10 + j, i));
}
}
}
}
return 0;
}
To be continued
如果你有任何建议或者批评和补充,请留言指出,不胜感激
以上是关于Codeforces Round #739 (Div. 3)(补题)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #739 (Div. 3) 题解
Codeforces Round #739 (Div. 3)A-F2
Codeforces Round #739 (Div. 3) ABCDEF1F2题解
Codeforces Round #739 (Div. 3) ABCDEF1F2题解
Codeforces Round #739 (Div. 3)(补题)
Codeforces Round #739 (Div. 3) F1. Nearest Beautiful Number (easy version)