题目
在走廊上有n个带锁的门,从1到n依次编号。最初所有的门都是关着的。我们从门前经过n次,每次都从1号门开始。在第i次经过时(i = 1,2,…, n)我们改变i的整数倍号锁的状态;如果门是关的,就打开它;如果门是打开的,就关上它。在最后一次经过后,哪些门是打开的,哪些门是关上的?有多少打开的门?
一、思路
将门牌号分解为i*j的形式,判断第几次循环会改变状态、如果存在偶数个因子则与初始状态相同、奇数个因子则状态相反。
如k = 20,分解成1x20,2x10,4x5,那么第1次,2次,4次,5次,10次,20次会经过第20号门。由此可见只需要判断分解出来的因子数为奇数还是偶数即可。
二、代码
public class text1 {
/*
* 题目信息获取: 输入n、循环n次、编号为当前循环次数的整数倍时变换状态、
*
* 思路:将门牌号分解为i*j的形式,判断第几次循环会改变状态、如果存在偶数个因子则与初始状态相同、奇数个因子则状态相反
*
* */
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();//获取总数
int number = 0;//统计开门个数
int close[] = new int[n + 1];//由于使用的是下标,所以最可能取到n
for (int i = 0; i < n; i++) {
int j = i + 1;
if (j * j <= n) {
close[(int) Math.pow(j, 2)]++;//1为开0为关
}
}
System.out.printf("打开门的编号:");
for (int i = 1; i <=n; i++) {
if (close[i]==1){
System.out.print(i + " ");
number++;
}
}
System.out.printf("\n关门的编号");
for (int i = 1; i <= n; i++) {
if (close[i] != 1) {
System.out.print(i + " ");
}
}
System.out.println("\n开门数:" + number);
}
}
测试数据
12
打开门的编号:1 4 9
关门的编号2 3 5 6 7 8 10 11 12
开门数:3
50
打开门的编号:1 4 9 16 25 36 49
关门的编号2 3 5 6 7 8 10 11 12 13 14 15 17 18 19 20 21 22 23 24 26 27 28 29 30 31 32 33 34 35 37 38 39 40 41 42 43 44 45 46 47 48 50
开门数:7