题目链接:1327: Lucky Numbers
Description
A lucky number is made by the following rules:
Given a positive integer sequence {x | 1 <= x <= n}. From the first number, delete the last one in every 2 numbers. Select the minimum that has not been unused from the rest numbers. This number is xi. Then delete the last number in every xi numbers.
幸运数字由以下规则制定:
给定正整数序列{x | 1 <= x <= n}。 从第一个数字中删除每2个数字中的最后一个。 从剩余数字中选择尚未使用的最小值。 这个数字是xi。 然后删除每个xi编号中的最后一个数字。
Input
There are several test cases, ended by the end of file.
Each test case has a positive integer n.(3<=n<=10000)
Output
Output the number of lucky numbers in one line.
在一行输出幸运数字的个数。
Sample Input
20
30
Sample Output
6
8
HINT
eg.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
For the first time, delete the last number in every two numbers. The sequence become 1 3 5 7 9 11 13 15 17 19
For the second time, the minimum number that has never been used is 3. Delete the last number in every 3 numbers. The sequence become 1 3 7 9 13 15 19
For the third time, the minimum number that has never been used is 7. Delete the last number in every 7 numbers. The sequence becomes 1 3 7 9 13 15.
Then you cannot delete any numbers. There are 6 numbers left over. So the answer is 6.
例如:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
显然不能每 1 个数删除 1 个,那就无意义了。
第一次,删除每 2 个数字中的最后一个数字。 序列变为1 3 5 7 9 11 13 15 17 19
第二次,删除每 3 个数字中的最后一个数字。 序列变为1 3 7 9 13 15 19
第三次,删除每 7 个数字中的最后一个数字。 序列变为1 3 7 9 13 15。
分析?
幸运数每次删除前的下标肯定不能被前面所有已知的幸运数整除。
注:2 是特殊数字。
代码?
/**
* Time 1514ms
* @author wowpH
* @version 2.2
* @date 2019年6月27日上午9:05:56
* Environment: Windows 10
* IDE Version: Eclipse 2019-3
* JDK Version: JDK1.8.0_112
*/
import java.io.InputStreamReader;
import java.util.Scanner;
public class Main {
private int[] luckyNum;// 幸运数数组
private int numberOfLucky;// 幸运数的个数
public Main() {
init();// 预处理
Scanner sc = new Scanner(new InputStreamReader(System.in));
while (sc.hasNext()) {
int n = sc.nextInt();
int i = 1;
while (i <= numberOfLucky) {
if (0 == n % luckyNum[i]) {
--n;
} else {
n -= n / luckyNum[i++];// 删除一部分数后,n的下标减小
}
}
System.out.println(n);
}
sc.close();
}
private void init() {
luckyNum = new int[1120];// 下标从1开始
luckyNum[1] = 2;// 注意:2不是幸运数,将它看做幸运数
numberOfLucky = 1;// 已知的幸运数的个数
int number = 3;// 当前数字
boolean flag;// 幸运数标志
do {
int index = number;// number的下标
flag = true;// 默认number是幸运数
// 如果number不能被已知的幸运数整除,
// 也就是每次删除的时候,恰好number留下来了,那么number是幸运数
for (int i = 1; i <= numberOfLucky; ++i) {
if (0 == index % luckyNum[i]) {
flag = false;// 能整除,所以number不是幸运数,退出
break;
}
// 删除前面的数后,number的下标应该减小
index -= index / luckyNum[i];
}
if (true == flag) {
luckyNum[index] = number;// 是幸运数,添加到幸运数数组里
++numberOfLucky;// 个数加1
}
++number;// 继续下一个数字
} while (number <= 10000);
}
public static void main(String[] args) {
new Main();
}
}