Codeforces Round #739 (Div. 3)
CF739 Div.3
D - Make a Power of Two
操作
- erase any digit of the number (it’s acceptable that the number before the operation has exactly one digit and after the operation, it is “empty”);
- add one digit to the right.
题意
通过两种操作将数字k变为2的整数次幂,求最小操作次数
思路
最差情况为全删。从最高位与2k匹配,记录最多匹配的位数。
公式:
- 原串长度 - 匹配位数 = 未匹配位数(匹配串:输入的数字串)
- 匹配串长度 - 匹配位数 = 删除位数(原串:2k)
- 最小操作次数 = 匹配串总长度 - 删除的位数 + 未匹配的位数
收获
- to_string类方法,将数值转换为字符串。
- 1ULL 就是将1标记为无符号长整型。其他类似。不区分大小写。
#include<bits/stdc++.h>
using namespcae std;
int main()
{
IOS;
int t;
cin >> t;
while (t--)
{
string s;
int ans = 10;
cin >> s;
for (int i = 0; i <= 63; i++)
{
string t = to_string(1ull << i);
int k = 0;
int sn = s.size(), tn = t.size();
for (int i = 0; i < sn; i++)
if (k < tn && s[i] == t[k]) k++;
ans = min(ans, sn + tn - 2 * k);
}
cout << ans << endl;
}
return 0;
}
太强了,比赛时以为很难,不敢写,代码实现能力还是太弱了。
E - Polycarp and String Transformation
题意
对于一个字符串s,一直执行以下操作直到字符串为空,字符串t初始是个空字符串:
- 将字符串s拼接到字符串t的后面,即 t = t + s
- 选择一个s中存在的字符c,删除字符串s中所有的c
现在给出字符串t,求原始字符串和删除字符的顺序,如果不存在输出-1。
思路
- 字符串的种类是越来越少的,所以我们可以倒序储存第一次出现的字符,求得字符删除顺序。
- 观察发现
第 1 个删除的字符在 t 串中出现的次数为 原串 s 中出现的次数的 1 倍
第 2 个删除的字符在 t 串中出现的次数为 原串 s 中出现的次数的 2 倍 - 以此类推,可求得原串总长度。然后模拟一遍题目中的操作,所得字符串若与输入相同则输出,否则输出-1
收获
- substr函数。
作用:substr()是C++语言函数,主要功能是复制子字符串,要求从指定位置开始,并具有指定的长度。如果没有指定长度_Count或_Count+_Off超出了源字符串的长度,则子字符串将延续到源字符串的结尾
#include<bits/stdc++.h>
#define endl "\n"
#define IOS ios::sync_with_stdio(0), cin.tie(0)
#define ft first
#define sd second
#define pll pair<ll, ll>
#define pii pair<int, int>
#define ll long long int
#define mt(a,b) memset(a, b, sizeof a)
//#define int long long
const int inf = 0x3f3f3f3f;
const int INF = 0x7fffffff;
using namespace std;
const int N = 1e5 + 10, M = 1e6 + 7;
map<int, int>mp;
string get_order(string t)
{
mp.clear();
string order;
int n = t.size();
for (int i = n - 1; i >= 0; i--)
{
if (mp[t[i] - 'a'] == 0) order += t[i];
mp[t[i] - 'a']++;
}
reverse(order.begin(), order.end());
return order;
}
string check(string s, string order)
{
int m = order.size();
string t;
for (int i = 0; i < m; i++)
{
t += s;
int n = s.size(); string ss;
for (int j = 0; j < n; j++)
if (s[j] != order[i]) ss += s[j];
s = ss;
}
return t;
}
int main()
{
IOS;
int T;
cin >> T;
while (T--)
{
string t; cin >> t;
int len = 0;
string order = get_order(t);
for (int i = 0; i < order.size(); i++)
len += mp[order[i] - 'a'] / (i + 1);
string s = t.substr(0, len);
if (t == check(s, order)) cout << s << " " << order << endl;
else cout << -1 << endl;
}
return 0;
}
摘自:https://blog.csdn.net/qq_43657674/article/details/119801188
F - Nearest Beautiful Number
该题有两个版本,easy版本k取值范围为 1 ~ 2, hard版本为 1 ~ 10.
题意
给定一个整数n求出一个 x,满足 x >= n 并且 x 是由不超过k个不同的数字组成。
样例 :
input:
4
1 1
221 2
177890 2
998244353 1
output:
1
221
181111
999999999
思路
暴力模拟
#include<bits/stdc++.h>
#define endl "\n"
#define IOS ios::sync_with_stdio(0), cin.tie(0)
#define ft first
#define sd second
#define pll pair<ll, ll>
#define pii pair<int, int>
#define ll long long int
#define mt(a,b) memset(a, b, sizeof a)
//#define int long long
const int inf = 0x3f3f3f3f;
const int INF = 0x7fffffff;
using namespace std;
const int N = 2e5 + 10, M = 1e6 + 7;
int a[N], b[N], c[N], aa[N];
bool ok(string s, int k)
{
sort(s.begin(), s.end());
return unique(s.begin(), s.end()) - s.begin() <= k;
}
int main()
{
IOS;
int T;
cin >> T;
while (T--)
{
string s; int k;
cin >> s >> k;
if (ok(s, k)) {cout << s << endl; continue;}
for (int i = s.size() - 1; i >= 0; i--)
for (s[i]++; s[i] <= '9'; s[i]++)
for (char ch = '0'; ch <= '9'; ch++)
{
for (int j = i + 1; j < s.size(); j++)
s[j] = ch;
if (ok(s, k)) goto F;
}
F:;
cout << s << endl;
}
return 0;
}