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();
}
}
}