Educational Codeforces Round 161 (Rated for Div. 2) --- E. Increasing Subsequences -- 题解

目录

E. Increasing Subsequences

题目描述:

思路解析:

代码实现:

方案1:会超数组长度200的限制 

方案2:可行答案:


E. Increasing Subsequences

题目描述:

        

思路解析:

        看到数据范围 2 - 1e18,首先想到一般方法无法解决,肯定要往二进制方法方面靠。

        然后想到二进制后,开始找规律,可以发现 :

       1位递增串可以解决2个递增序列,

       2位递增串可以解决4个递增序列,

      3位递增串可以解决8个递增序列,符合二进制,那么其中包含的递增序列都重复的包含了空串这个递增序列,那么其实1位可以解决一个递增序列,2位可以解决三个递增序列,3位可以解决七个递增序列。其实也可以暗含的转为二进制(都多余的加一位)。

        这种方法可行,但是因为题目要求数组长度只能为 [1,200],那么这个方法会超数组范围,因为我们是根据二进制位一位一位解决的,每位之间的信息没有关联起来。假如我们解决1101(二进制)这个数字,我们是单独的处理这四位,这四位之间没有联系。  

        1101(二进制) --- 答案1: 4 5 3 0 1 2 -1  答案2: 1 -1 2 3 -2

        那如何让每位联系起来,来节省空间,观察 4 5 3这个序列可以发现,当序列为4,可以解决两个递增序列,当序列为4 5,可以解决4个递增序列,当序列为 4 5 3可以解决五个递增序列。

        从中又可以发现,如果当一个序列 X,可以解决Y个递增序列,序列X的最大值为max,最小值为min,那么 序列F={X, max + 1}可以解决2*Y个递增序列,那么G={X, min-1}可以解决Y+1个递增序列。此时又用到了每位之间的关联,又体现了二进制,问题解决。

代码实现:

方案1:会超数组长度200的限制 

import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        Scanner input = new Scanner(System.in);
        int t = input.nextInt();
        for (int o = 0; o < t; o++) {
            long x = input.nextLong();
            x -= 1;
            int p = 1;
            int max = 1000;
            int[] res = new int[2500];
            int size = 0;
            while (x > 0){
                if ((x & 1) == 1){
                    int m = size + p - 2;
                    size = size + p - 1;
                    for (int i = 0; i < p - 1; i++) {
                        res[m--] = max--;
                    }
                    res[size++] = max--;
                }
                p++;
                x >>= 1;
            }
            System.out.println(size);
            for (int i = 0; i < size; i++) {
                System.out.print(res[i] + " ");
            }
            System.out.println();
        }
    }



}

方案2:可行答案:

import java.io.*;
import java.util.*;

public class Main {
    static int size = 0;
    static int mx = 0;
    static int my = 0;
    static int[] res;
    public static void main(String[] args) throws IOException {
        Scanner input = new Scanner(System.in);
        int t = input.nextInt();
        for (int o = 0; o < t; o++) {
            long x = input.nextLong();
            mx = 0;
            size = 0;
            my = 0;
            res = new int[2500];
            dfs(x);
            System.out.println(size);
            for (int i = 0; i < size; i++) {
                System.out.print(res[i] + " ");
            }
            System.out.println();
        }
    }

    public static void dfs(long x) {
        if (x == 1) return;
        if (x % 2 == 1){
            dfs(x - 1);
            res[size++] = --mx;
        }else {
            dfs(x >> 1);
            res[size++] = ++my;
        }
    }

}

                  

"educational codeforces round 103 (rated for div. 2)"是一个Codeforces平台上的教育性比赛,专为2级选手设计评级。以下是有关该比赛的回答。 "educational codeforces round 103 (rated for div. 2)"是一场Codeforces平台上的教育性比赛。Codeforces是一个为程序员提供竞赛和评级的在线平台。这场比赛是专为2级选手设计的,这意味着它适合那些在算法和数据结构方面已经积累了一定经验的选手参与。 与其他Codeforces比赛一样,这场比赛将由多个问题组成,选手需要根据给定的问题描述和测试用例,编写程序来解决这些问题。比赛的时限通常有两到三个小时,选手需要在规定的时间内提交他们的解答。他们的程序将在Codeforces的在线评测系统上运行,并根据程序的正确性和效率进行评分。 该比赛被称为"educational",意味着比赛的目的是教育性的,而不是针对专业的竞争性。这种教育性比赛为选手提供了一个学习和提高他们编程技能的机会。即使选手没有在比赛中获得很高的排名,他们也可以从其他选手的解决方案中学习,并通过参与讨论获得更多的知识。 参加"educational codeforces round 103 (rated for div. 2)"对于2级选手来说是很有意义的。他们可以通过解决难度适中的问题来测试和巩固他们的算法和编程技巧。另外,这种比赛对于提高解决问题能力,锻炼思维和提高团队合作能力也是非常有帮助的。 总的来说,"educational codeforces round 103 (rated for div. 2)"是一场为2级选手设计的教育性比赛,旨在提高他们的编程技能和算法能力。参与这样的比赛可以为选手提供学习和进步的机会,同时也促进了编程社区的交流与合作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Studying~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值