【牛客】J.闯关的lulu

2018年牛客多校算法寒假训练营练习比赛(第一场)

题目描述
  勇者lulu某天进入了一个高度10,000,000层的闯关塔,在塔里每到一层楼,他都会获得对应数量的0 1(看情况获得),然后塔里有一个法则,当你身上某个数字达到一个特定的数量时,它们会合成为下一个数字,现在问题来了,当lulu从1层到达第n层的时候,他身上的数字是多少。

第1层 0
第2层 11
第3层 110
第4层 21
第5层 210
第6层 22
第7层 220
第8层 2211
第9层 22110
第10层 2221
第11层 22210
第12层 3

输入描述:
第一行是样例数T(T<100)
第2到2+T-1行每行有一个整数n(0<n<= 1 0 7 10^7 107)。

输出描述:
从大到小输出lulu到达第n层时身上的数字
示例输入

4
1
2
3
20

输出

0
11
110
32211

备注:
对于100%的数据,
0 < T <= 100
0 < n <= 1 0 7 10^7 107

题解

分析样例可得,两个0组成一个1,三个1组成1个2,4个2组成一个3,然后从第一层开始,奇数层多一个0,偶数层多一个0和一个1。
思路:先把第n层转为全是0的个数,再逐个模,然后除,再模,再除等。

import java.util.*;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        Scanner in = new Scanner(System.in);
        int T = in.nextInt();
        //v[i]记录 i 需要在结果出现几次
        int[] v = new int[10005];
        //T个样例
        for (int count = 0; count < T; count++) {
    
    
            //第n层
            int n = in.nextInt();

            //转为0的个数
            int zerosum = n + (n / 2) * 2;
            // System.out.println("zeroCount: "+zerosum);

            int i = 1;
            while (zerosum != 0) {
    
    
                //从2开始取余
                i++;
                v[i - 2] = zerosum % i;
                zerosum /= i;
            }
            // System.out.println("i: "+i);

            //倒序输出
            for (; i >= 0; i--) {
    
    
                //v[i]是几就输出几次
                while (v[i] > 0) {
    
    
                    System.out.print(i);
                    v[i]--;
                }
            }
            System.out.println();
        }
    }
}

解法二:
不变成全0直接进行转换,从有0和有1开始凑:

import java.util.*;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        Scanner in = new Scanner(System.in);
        int T = in.nextInt();
        //T个样例
        for (int count = 0; count < T; count++) {
    
    
            //到达第n层
            int n = in.nextInt();
            int i, x, j, k;
            //存储每个数字有几个,v0表示0的个数,v1表示1的个数
            int[] v = new int[10005];
            //第n层有n个0,n / 2个1
            v[0] += n;
            v[1] += n / 2;
            //i记录合成的数字,逐次累加从0开始,x表示合成的个数,例如2个0能够合成1
            i = 0;
            x = 2;
            while (true) {
    
    
                //如果条件不成立,说明这个数字的个数大于合成需要的个数,需要执行合成
                if (v[i] / x == 0) {
    
    
                    break;
                }
                v[i + 1] += v[i] / x;
                v[i] %= x;
                x++;
                i++;
            }
            
            //输出
            //外层循环表示输出哪个数字,从最大到0依次递减
            for (j = i; j >= 0; j--) {
    
    
                //内层表示输出几个数字
                for (k = 0; k < v[j]; k++) {
    
    
                    System.out.print(j);
                }
            }
            System.out.println();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_44033208/article/details/131861495