Codeforces Round #739 (Div. 3)

链接:https://codeforces.com/contest/1560

总体评价:区分度不错,比之前的div3要难一些。

A

预处理出前1000个,直接输出即可。

#include <bits/stdc++.h>
const int N = 100050;
const int INF = 1 << 30;
typedef long long ll;
using namespace std;
int n, x, num, ans[N];
int main() {
cin >> n;
for(int i = 1; num <= 1000; i++) {
if(i % 10 == 3 || i % 3 == 0)
continue;
ans[++num] = i;
}
for(int i = 1; i <= n; i++) {
cin >> x;
cout << ans[x] << endl;
}
return 0;
}

B

简简单单画出前几个的情况可以找到规律,加入一些特判的点即可。

#include <bits/stdc++.h>
const int N = 100050;
const int INF = 1 << 30;
typedef long long ll;
using namespace std;
int t, a, b, c, d;
int main() {
cin >> t;
while(t--) {
cin >> a >> b >> c;
d = abs(a - b);
if(abs(a - b) == 1 || min(a, b) > abs(a - b) || c > 2 * d) {
cout << "-1" << endl;
continue;
}
c <= d ? cout << c + d << endl : cout << c - d << endl;
}
return 0;
}

C

也是找规律题。以左上角的1为中心,向外画圈,看成{1},{2,3,4},{5,6,7,8,9}......这样分组。

看第1列,1,4,9,....n2。看第一行,1,2,5,...,(n1)2+1。看左上到右下的那条对角线,1,3,7,...,n2n+1

首先初步判定k是在第几组(环),109<32000,时间复杂度是可以接受的。

然后再判断得到k时是行不变还是列不变,输出即可。

#include <bits/stdc++.h>
const int N = 100050;
const int INF = 1 << 30;
typedef long long ll;
using namespace std;
int t, x, n;
int main() {
cin >> t;
while(t--) {
cin >> x;
for(int i = 1; i <= 32000; i++) {
if(i * i >= x) {
n = i;
break;
}
}
if(x <= n * n - n + 1)
cout << x - (n - 1) * (n - 1) << " " << n << endl;
else
cout << n << " " << n - (x - (n * n - n + 1)) << endl;
}
return 0;
}

D

题意

根据题中的规则进行操作,求将给定数变为一个2的任意次幂的最少操作数。

思路

看数据范围,可以知道我们最多只需预处理到1018,在这个上限以内符合条件的数在60个左右,我们是可以接受的。

所以可以进行枚举,找到最小的答案。

答案怎么算?其实就是一个双指针的操作。遇到相同的统计一下(++cnt),一起移动指针,否则只移动题中所给的字符串的指针,直到遍历完其中一个字符串。操作次数也就很好算了,等效为把原字符串中与答案不同的先删掉+答案有但原字符串没有的。

#include <bits/stdc++.h>
const int N = 100;
const int INF = 1 << 30;
typedef long long ll;
using namespace std;
int k, ans;
ll bin[N];
string s;
int calc(ll x) {
string t = "";
while(x) {
t += (x % 10) + '0';
x /= 10;
}
reverse(t.begin(), t.end());
int cnt = 0, j = 0, l = 0;
while(j < s.length() && l < t.length()){
if(s[j] == t[l]) {
++cnt;
j++;
l++;
}
else j++;
}
return s.length() + t.length() - cnt * 2;
}
int main() {
ios::sync_with_stdio(false);
cin >> k;
bin[0] = 1;
for(int i = 1; i <= 62; i++) bin[i] = bin[i - 1] * 2;
while(k--) {
ans = INF;
cin >> s;
for(int i = 0; i <= 62; i++) ans = min(ans, calc(bin[i]));
cout << ans << endl;
}
return 0;
}

F1

题意

给定数x,k(k[1,2]),找到最小的y,使得yx并且保证y的十进制表示中最多出现k种数字。

思路

这题要想分类讨论还是太难了......

k=1,则可以通过枚举找到答案。

k=2,我们可以枚举确定答案是由哪两个数字组成,同时按贪心思路构造出较小的答案,进行统计。很难想。

#include <bits/stdc++.h>
using namespace std;
int t, k;
set<char> o;
string s;
string calc(char x) {
string y = "";
for(int i = 0; i < s.length(); i++) y += x;
return y;
}
void solve1() {
for(char i = '0'; i <= '9'; i++) {
string t = calc(i);
if(t > s) {
cout << t << endl;
return ;
}
}
}
void solve2() {
string t = calc('9');
for(char i = '0'; i <= '9'; i++) {
for(char j = i + 1; j <= '9'; j++) {
for(int l = 0; l < s.length(); l++) {
if(s[l] < j) {
string g = s;
g[l] < i ? g[l] = i : g[l] = j;
for(int p = l + 1; p < g.length(); p++) g[p] = i;
if(t > g) t = g;
}
if(s[l] != i && s[l] != j) break;
}
}
}
cout << t << endl;
}
int main() {
ios::sync_with_stdio(false);
cin >> t;
while(t--) {
o.clear();
cin >> s >> k;
for(int i = 0; i < s.length(); i++) o.insert(s[i]);
if(o.size() <= k) {
cout << s << endl;
continue;
}
k == 1 ? solve1() : solve2();
}
return 0;
}

还有个超时的做法,就是k=2时用dfs来做,也贴在这里吧......

#include <bits/stdc++.h>
using namespace std;
int t, k;
set<char> o;
string s;
string calc(char x) {
string y = "";
for(int i = 0; i < s.length(); i++) y += x;
return y;
}
void solve1() {
for(char i = '0'; i <= '9'; i++) {
string t = calc(i);
if(t > s) {
cout << t << endl;
return ;
}
}
}
void dfs(int step, char t1, char t2, string &t, string p) {
//cout << t << " " << p << endl;
if(step == 2 && p == "0")
return ;
if(step != 1 && p[0] < s[0])
return ;
if(step == s.length() + 1) {
if(p < t && p > s) {
t = p;
return ;
}
return ;
}
string last = p;
dfs(step + 1, t1, t2, t, p + t1);
p = last;
dfs(step + 1, t1, t2, t, p + t2);
p = last;
}
void solve2() {
string t = "", p = "";
t = calc('9');
for(char i = '0'; i <= '9'; i++) {
for(char j = '0'; j <= '9'; j++) {
if(i == j)
continue;
// cout << *it1 << " " << *it2 << endl;
dfs(1, i, j, t, p);
}
}
cout << t << endl;
}
int main() {
ios::sync_with_stdio(false);
cin >> t;
while(t--) {
o.clear();
cin >> s >> k;
for(int i = 0; i < s.length(); i++) o.insert(s[i]);
if(o.size() <= k) {
cout << s << endl;
continue;
}
k == 1 ? solve1() : solve2();
}
return 0;
}
posted @   BeyondLimits  阅读(57)  评论(3编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示