【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;
}


记录菜鸟的成长过程:




最后唠叨几句:

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

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

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

要继续努力才行。

猜你喜欢

转载自www.cnblogs.com/Ayanowww/p/12051491.html