【cf比赛记录】Codeforces Round #606 (Div. 2, based on Technocup 2020 Elimination Round 4)

比赛传送门

只能说当晚状态不佳吧,有点头疼感冒的症状。也跟脑子没转过来有关系,A题最后一步爆搜没能立即想出来,B题搜索没有用好STL,C题也因为前面两题弄崩了心态,最后,果然掉分了。

A:简单数学

B:数学+排序

C:字符串搜索

A

// https://codeforces.com/contest/1277/problem/A
/*
题意:
给出一个数,求不大于该数的完美整数的个数(完美整数指全是一个数组成的数字,如:111, 333333, 444444, 9, 8888 ...) 分析:
因为求不大于的,那位数小于当前数的肯定满足,所以可以先得到 ans = (位数 - 1) * 9
然后就从同位的完美整数开始比较,比当前数小的就 ans++
因为数最大是 1e9, 我用 char[1e9] MLE 了...
*/
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std; long long n[20][20];
int T;
long long num; // 完美整数打表
void init(){
for(int i = 1; i <= 10; i++){
for(int j = 1; j <= 10; j++){
n[i][j] = n[i - 1][j] * 10 + j;
}
}
} int main()
{
init();
scanf("%d", &T);
while(T--){
long long ans = 0;
scanf("%I64d", &num);
if(num < 10) ans = num;
else {
int len = 0;
for(int i = num; i; i /= 10) len++; // 求当前数的位数
ans += (len - 1) * 9; // 最高位的遍历
for(int i = 1; i <= 9; i++){
if(n[len][i] <= num) {
ans++;
}
}
}
printf("%I64d\n", ans);
}
return 0;
} //2
//1000000000
//999999999

B

// https://codeforces.com/contest/1277/problem/B
/*
题意:
在 n 个数里,把偶数都除以二,直至除到全为奇数为止,相同的偶数可以同时进行,问最少步可以除完 分析:
既然相同的偶数可以同时进行,那就找最后奇数相同的时候,它是2的倍数时最大的那个数的步骤数就行
例如 6 与 12 的话,只需要知道 12 除 2 除到奇数时需要 2 次即可 ==== 12 / 2 = 6, 两个 6 同时除以 2 就是 3
关键是怎么记录这些偶数对应的奇数 ---- 选好STL很关键,我比赛时选了个数组遍历已存的奇数而超时了,补题用map就很舒服 109ms,比我朋友 500多ms 要快
先排序,从大的先找,用map存奇数,当已经有奇数k存在时,就不需要计算当前的偶数了
*/
#include<iostream>
#include<cstdio>
#include<map>
#include<algorithm>
using namespace std; // two:存 2 的次方数 num:存 n 个数据
int two[40], num[200005];
int T, n, cnt; void init_two(){
two[0] = 1;
for(int i = 1; i <= 32; i++){
two[i] = two[i - 1] * 2;
}
} int main()
{
init_two(); // 打表
scanf("%d", &T);
while(T--){
scanf("%d", &n);
for(int i = 0; i < n; i++) scanf("%d", &num[i]);
sort(num, num + n); // 排序 int ans = 0;
map<int, int> m;
for(int i = n - 1; i >= 0; i--){ // 从大往小找
int tmp = num[i];
if(tmp & 1) continue; // 如果是奇数就跳过
for(int t = 30; t >= 1; t--){ // 2 的次方数也是从大往小找
if(tmp % two[t] == 0){ // 此时能整除的时候就是所需要的步数
int k = tmp / two[t];
// printf("k:%d m:%d\n", k, m[k]);
if(m[k]) break; // 如果 k 已经存在则不用计算
m[k]++;
ans += t;
break;
}
}
}
printf("%d\n", ans);
}
return 0;
}

C

// https://codeforces.com/contest/1277/problem/C
/*
题意:
给一个字符串,要求剔除字符串里的最少个字符,使其中不含"one","two"两个子序列
输出需要剔除字符的最少个数以及它们所在的位置 分析:
有三种情况,分别是 "one", "two", "twone"
最后一种比较好理解,直接去掉中间的 'o' 就不存在 "two" 与 "one" 了
而"one"与"two"情况时一样处理,剔除中间那位,因为像 "oone" 这种的话,剔除前面的'o'要剔除两次(后面的'e'亦然)
整体比较暴力
*/
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std; int T;
char ch[150005];
int ans[50004]; int main()
{
scanf("%d", &T);
while(T--){
int cnt = 0;
scanf("%s", ch);
int len = strlen(ch) - 2;
for(int i = 0; i < len; i++){
if(ch[i] == 'o' && ch[i + 1] == 'n' && ch[i + 2] == 'e') { // one 的情况
ans[cnt++] = i + 2;
i += 2;
}
else if(ch[i] == 't' && ch[i + 1] == 'w' && ch[i + 2] == 'o'){ // two 的情况
if(ch[i + 3] == 'n' && ch[i + 4] == 'e'){ // twone 的情况
ans[cnt++] = i + 3;
i += 4;
}
else {
ans[cnt++] = i + 2;
i += 2;
}
}
}
printf("%d\n", cnt);
for(int i = 0; i < cnt; i++){
if(i != 0) printf(" ");
printf("%d", ans[i]);
}
printf("\n");
}
return 0;
}

记录菜鸟的成长过程:

【cf比赛记录】Codeforces Round #606 (Div. 2, based on Technocup 2020 Elimination Round 4)



最后唠叨几句:

周日(12月15日)没有打CF两场比赛,而是去广州找我三位好基友玩耍了(两名是广工的学生,一名是华南理工的学生)。其中一位是复读才考上了广工的机械类专业的。现在他是大一生的身份去参加了一个社团组织,去做机器人。当天他带我们参观了他们的实验室,实验室里还有两位大三的师兄在备考明年的考研。他们要做成的机器人至少需要三个专业的学生协同配合,其中一位就需要计算机专业类的学生负责写代码一方面。听他的描述,写代码需要与摄像头结合起来,要会使用单片机等等与硬件相结合的东西。听得我着实有点羡慕,也引起了我的思考。

好强的大一生,像广工这等高校里面的人都这么强吗?越发觉得自己一直在摸鱼。学校的环境是改不了,但自己可以改变的吧?办法总比困难多。

再次意识到自己与外面的差距,即便在自己本校里,自己与校内的dalao也有很大的差距。

要继续努力才行。

上一篇:解决Bug步骤


下一篇:【cf比赛记录】Codeforces Round #601 (Div. 2)