Codeforces-Round-929-Div-3

注意: \color{red}{注意:} 注意: 个人博客传送门

A. Turtle Puzzle: Rearrange and Negate

思路:

  • 因为可以任意排序,所以只需要输出每一个数绝对值的总和

时间复杂度: O ( n ) O(n) O(n)

void solve() {
    int n;
    std::cin >> n;

    std::vector<int> a(n);
    for (int i = 0; i < n; i++) {
        std::cin >> a[i];
        a[i] = abs(a[i]);
    }
    std::cout << std::accumulate(a.begin(), a.end(), 0) << "\n";
}

B. Turtle Math: Fast Three Task

思路:

  • 每次可以进行删除一个数或者选一个数加1
  • 如果最终的余数(mod)为0,就一定不需要操作
  • 如果余数为2,或者序列中存在某个数的余数等于mod,就只需要操作1
  • 否则一定需要2

时间复杂度: O ( n ) O(n) O(n)

void solve() {
    int n;
    std::cin >> n;

    std::vector<int> a(n);
    for (int i = 0; i < n; i++) {
        std::cin >> a[i];
        a[i] %= 3;
    }

    int sum = std::accumulate(a.begin(), a.end(), 0);
    int mod = sum % 3;
    if (mod == 0) {
        std::cout << "0\n";
        return ;
    }

    if (std::count(a.begin(), a.end(), mod) || mod == 2) {
        std::cout << "1\n";
    } else {
        std::cout << "2\n";
    }
}

C. Turtle Fingers: Count the Values of k

思路:

  • 首先我们观察这个式子 l = k × a x × b y l=k\times a^{x} \times b^{y} l=k×ax×by
  • 可以看出, a x a^x ax b y b^y by 一定是 l l l 的因子,那么,我们可以得到 { l   %   a x = 0 l   %   b y = 0 \begin{cases} l \space \% \space a^x = 0 \\ l \space \% \space b^y = 0 \end{cases} {l % ax=0l % by=0
  • 然后我们直接枚举 a a a b b b 的指数即可,然后推导出 k = l a x b y k = \frac{\frac{l}{a^x}}{b^y} k=byaxl

时间复杂度: O ( l o g a l × l o g b ( l / i ) ) O(log_al \times log_b(l / i)) O(logal×logb(l/i))

void solve() {
    int a, b, l;
    std::cin >> a >> b >> l;

    std::set<int> st;
    for (int i = 1; l % i == 0; i *= a) {
        for (int j = 1; l / i % j == 0; j *= b) {
            st.insert(l / i / j);
        }
    }
    std::cout << st.size() << "\n";
}

D. Turtle Tenacity: Continual Mods

思路:

  • 一个序列所有数从左到右互相取模,可以发现,只要最小的数在最前面,那么一定最终答案不为0
  • 所以,我们可以判断,最小的数的个数,如果为1,那么一定可以
  • 如果在除去最小的数的剩下的序列中,找到一个数mod min != 0,那么一定可以,因为它的余数一定比min更小,那就可以把这个数放到那个最小的数前面,构成一个以更小的数开头的新序列

时间复杂度: O ( n ) O(n) O(n)

void solve() {
    int n;
    std::cin >> n;

    std::vector<int> a(n);
    for (int i = 0; i < n; i++) {
        std::cin >> a[i];
    }
    std::sort(a.begin(), a.end());  

    int min = a[0];
    if (std::count(a.begin(), a.end(), min) == 1) {
        std::cout << "YES\n";
        return ;
    }
    for (int i = 1; i < n; i++) {
        if (a[i] % min != 0) {
            std::cout << "YES\n";
            return ;
        }
    }
    std::cout << "NO\n";
}

E. Turtle vs. Rabbit Race: Optimal Trainings

题目大意为:

  • 给你一个序列,你可以获得分数,只要你可以在[l, r]这个区间内获得尽可能多的能量,但不能大于u,当然,你也可以获得超出给定值(u)的能量,但这样会使你的能量减少。求一个你可以获得最多能量的区间右端点r

思路:

  • 可以先求个前缀和,这样就保证了单调性,然后二分右端点
  • 只要发现r == n时,u - sum[l, r] < s[l, r + 1] - u,那么输出r
  • 否则s[l, r + 1] - u < u - sum[l, r],这样可以获得更大的分数,输出r + 1

时间复杂度: O ( q × l o g n ) O(q\times logn) O(q×logn)

void solve() {
    int n;
    std::cin >> n;

    std::vector<int> a(n);
    for (int i = 0; i < n; i++) {
        std::cin >> a[i];
    }

    std::vector<i64> s(n + 1);
    for (int i = 0; i < n; i++) {
        s[i + 1] = s[i] + a[i]; 
    }

    int q;
    std::cin >> q;

    while (q--) {
        int l, u;
        std::cin >> l >> u;

        int left = l, right = n;
        while (left < right) {
            int mid = left + right + 1 >> 1;
            if (u + s[l - 1] >= s[mid]) {
                left = mid;
            } else {
                right = mid - 1;
            }
        }
        if (left == n || u - (s[right] - s[l - 1]) < s[right + 1] - s[l - 1] - u) {
            std::cout << right << " ";
        } else {
            std::cout << right + 1 << " ";
        }
    }
    std::cout << "\n";
}
  • 28
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值