Codeforces Round 907 (Div. 2) 题解 A-B

目录

  • [A - Sorting with Twos](#A - Sorting with Twos)
  • [B - Deja Vu](#B - Deja Vu)

A - Sorting with Twos

原题链接

题目描述

给你一个长度为 n n n 的数组 a a a,在每次操作中,你可以选择一个非负整数 m m m ( 2 m ≤ n 2^m \leq n 2m≤n),然后让所有的 a i a_i ai ( 1 ≤ i ≤ 2 m 1 \le i \leq 2^m 1≤i≤2m)都减去 1 1 1,问是否可以通过一定次数使得数组 a a a 变成非递减数组。

思路:思维+暴力修改

  • 由于 n n n很小,我们每次从坐标 1 1 1开始,往后暴力修改每一个长度为 2 m 2^m 2m的区间,这样一定可以让前面的更小,如果这样修改都无法满足,那么为No
java 复制代码
public static void solve() throws IOException{
    int n = readInt();
    int[] arr = utils.nextIntArray(n);
    int m = 0;
    boolean f = true;
    int k = 10;
    while (k-- > 0) {
    	// 如果在修改区间时,已经遇到arr[i - 1] > arr[i],那么肯定无法满足题意
    	// 因为该区间已经不可再分,即无法将arr[i - 1]变为更小的值
        for (int i = 1; i <= Math.pow(2, m) && i <= n; i++) {
            if (arr[i - 1] > arr[i]) {
                f = false;
                break;
            }
        }
        if (!f) break;
        // 暴力将前面都修改为最小值
        for (int i = 1; i <= Math.pow(2, m) && i <= n; i++) {
            arr[i] = 0;
        }
        m++;// 增加区间长度
    }
    printWriter.println(f ? "YES" : "NO");
}

B - Deja Vu

原题链接

题目描述

给你一个长度为 n n n 的正整数数组 a a a 和一个长度为 q q q 的正整数数组 x x x,一共有 q q q 次修改,对于每次修改,如果 a j ( 1 ≤ j ≤ n ) a_j(1 \leq j \leq n) aj(1≤j≤n)可以被 2 x i ( 1 ≤ i ≤ q ) 2^{x_i}(1 \leq i \leq q) 2xi(1≤i≤q)整除,那么就把 2 x i − 1 2^{x_i-1} 2xi−1 加到 a j a_j aj 上。求在完成 q q q 次修改后的 a a a 数组。

思路:思维+观察

  • 如果 a j a_j aj 可以被 2 x i 2^{x_i} 2xi整除,那么当 a j a_j aj加上 2 x i − 1 2^{x_{i-1}} 2xi−1后, a j a_j aj之后可以整除的 2 x k 2^{x_k} 2xk 一定小于 2 x i 2^{x_i} 2xi,即 k < i k \lt i k<i,比如 32 32 32 可以整除 2 5 2^5 25 ( i = 5 ) (i = 5) (i=5),那么 32 32 32 加上 2 4 ( i − 1 = 4 ) 2^4(i-1 = 4) 24(i−1=4)后变为 48 48 48 ,而 48 48 48 只能整除 2 p ( p < 5 ) 2^p(p \lt 5) 2p(p<5)。
  • 所以对于每一个 a j a_j aj,当他可以整除 x i x_i xi时,求出 x i x_i xi在 x x x数组中的严格下降子序列即可。但是 x i x_i xi的严格下降子序列我们应该预处理好。
java 复制代码
public static void solve() throws IOException{
    int n = readInt(), q = readInt();
    int[] a = utils.nextIntArray(n);
    int[] x = utils.nextIntArray(q);
    List<Integer>[] lists = new List[40];
    Arrays.setAll(lists, g -> new ArrayList<>());
    for (int i = 1; i <= 30; i++) {
        lists[i].add(40);// xi最大为30,这里我们添加一个更大的值,保证降序
    }
    // 求出 xi的严格下降序列
    for (int i = 1; i <= 30; i++) {
        for (int j = 1; j <= q; j++) {
            if (x[j] < lists[i].get(lists[i].size() - 1)) {//比上一次的小就添加
                lists[i].add(x[j]);
            }
        }
    }
    int[] have= new int[40];// xi是否出现过
    for (int i = 1; i <= q; i++) {
        if (have[x[i]] == 0) {
            have[x[i]] = i;
        }
    }
    for (int i = 1; i <= n; i++) {
    	// 求出 ai的因数可以有多少个 2
        int k = 0, t = a[i];
        while (t % 2 == 0 && t != 0) {
            k++;
            t /= 2;
        }
        // 求出最近的能被 ai整除的 x数组的数 x^k
        while (k >= 1 && have[k] == 0) {
            k--;
        }
        // 根据 x^k的严格下降序列,求出最终的 ai
        List<Integer> ps = lists[k];
        for (Integer p : ps) {
            if (a[i] % Math.pow(2, p) == 0) {
                a[i] += Math.pow(2, (p - 1));
            }
        }
    }
    for (int i = 1; i <= n; i++) {
        printWriter.print(a[i] + " ");
    }
    printWriter.println();
}
相关推荐
C++ 老炮儿的技术栈2 分钟前
什么是函数重载?为什么 C 不支持函数重载,而 C++能支持函数重载?
c语言·开发语言·c++·qt·算法
yychen_java38 分钟前
R-tree详解
java·算法·r-tree
MarkHard1231 小时前
Leetcode (力扣)做题记录 hot100(62,64,287,108)
算法·leetcode·职场和发展
一只鱼^_2 小时前
牛客练习赛138(首篇万字题解???)
数据结构·c++·算法·贪心算法·动态规划·广度优先·图搜索算法
一只码代码的章鱼2 小时前
Spring的 @Validate注解详细分析
前端·spring boot·算法
邹诗钰-电子信息工程2 小时前
嵌入式自学第二十一天(5.14)
java·开发语言·算法
↣life♚3 小时前
从SAM看交互式分割与可提示分割的区别与联系:Interactive Segmentation & Promptable Segmentation
人工智能·深度学习·算法·sam·分割·交互式分割
zqh176736464693 小时前
2025年阿里云ACP人工智能高级工程师认证模拟试题(附答案解析)
人工智能·算法·阿里云·人工智能工程师·阿里云acp·阿里云认证·acp人工智能
fie88893 小时前
用模型预测控制算法实现对电机位置控制仿真
算法
Kent_J_Truman3 小时前
【交互 / 差分约束】
算法