一个java面试题。
现有一个酒店有100个房间,依次编号为1到100,第一个服务员经过,将所有房间门打开上;第二个服务员经过将所有编号为2的倍数房门关上;第三个服务员经过将所有编号为3倍数的房门打开的关上,关闭的
打开。第四五个服务员依此类推,问第100个服务员进来,有哪些门是打开的。 --------------------编程问答-------------------- 奇数开。。。。。。。。。。。。。。。。。。。。。 --------------------编程问答-------------------- 奇数开。。。 --------------------编程问答-------------------- 这个问题毫无意义啊,不会是提问出错了吧 --------------------编程问答-------------------- 奇数的平方。
分别找到1-100的因数,例如9的因数有1、3、9,也就是第1、3、9个服务员会改变门的状态。所以最后是打开的。其他数字类似,最后得到奇数的平方数的门是打开的。
也就是,1、9、25、49、81 --------------------编程问答--------------------
import java.util.List;
import java.util.ArrayList;
class Room {
boolean isOpen = true;
public void setIsOpen(boolean isOpen) {
this.isOpen = isOpen;
}
}
public class Test {
public static void main(String[] args) {
List<Room> list = new ArrayList<Room>(100);
for(int i = 0; i < 100; i ++) {
list.add(new Room());
}
for(int i = 2; i <= 100; i ++) {
for(int j = 2; j <= list.size(); j++) {
if(j % i == 0) {
list.get(j - 1).setIsOpen(!list.get(j - 1).isOpen);
}
}
}
for(int i = 0; i < list.size(); i ++) {
System.out.print(list.get(i).isOpen?(i+1) + " ":"");
}
}
}
不知道是不是这样 --------------------编程问答-------------------- 应该是1-10的平方吧,也就是1,4,9,16....100。
每个数X总能拆分成X和Y的乘积(eg:3=1*3,6=1*6,6=2*3),只要不是一个数的平方,一个人打开房门就有一个人关闭房门。只有自己的平方根打开房门,而没有对应的人来关闭房门 --------------------编程问答-------------------- --------------------编程问答-------------------- 其实这个题就是求一个数的因数有多少个只有这个房间号的因数才能改变状态,当因数个数为奇数打开,偶数时关闭
代码
public static void main(String[] args)
{
int n,sum=0;
for(n=1;n<101;n++)
{
for(int i=1;i<=n;i++)
{
if(n%i==0)
sum=sum+1;
}
if(sum%2==1)
System.out.println(n);
sum=0;
}
}
1
4
9
16
25
36
49
64
81
100
结果
--------------------编程问答-------------------- 不对不对,四楼正解 结果
1
9
25
49
81
--------------------编程问答-------------------- 我不知道我的习惯好不好,以前遇到这样的问题的时候都是简单的想想就给答案,但是现在是想用笔真的去一个一个的计算出来。
首先说奇数开的是理解错了意思,那个循环是二三服务员的循环,而不是三服务员的循环。
第一个服务球员完成后---------------------
都开
第二个服务员完成后---------------------
1,3,5,。。。。99开
第三个服务员完成后---------------------
四种情况,
偶数并且为3的倍数,开
偶数并且不为3的倍数,关
奇数并且为3的倍数,关
奇数并且不为3的倍数,开
第四个服务员完成后---------------------
偶数并且为3的倍数,关
偶数并且不为3的倍数,关
奇数并且为3的倍数,关
奇数并且不为3的倍数,开
第五个服务员完成后---------------------
偶数并且为3的倍数,开
偶数并且不为3的倍数,关
奇数并且为3的倍数,开
奇数并且不为3的倍数,开
4和5的是一组的话,应该和6,7是一个对应的循环,也就是说4,5,6,7做完后等于什么都没干。
1-3,4-7,8-11,。。。。96-99,(4到99的可以忽略)100
最后的结果应该是第四个人完成后结果。。
时间有点急,暂时就想到这些,如果考虑不周的请指出,谢谢。 --------------------编程问答-------------------- 4号门,被1号服务员打开,2号服务员关上,四号服务员打开,之后就没有服务员可以操作这扇门了!
所以1,9,25……是有问题的,应该是1,4,9,16,……这是序列 --------------------编程问答--------------------
import java.util.Arrays;
public class Hello {
public static void main(String[] args) {
boolean[] status = new boolean[101];
Arrays.fill(status, true); // Open all doors.
for (int waiterIndex = 2; waiterIndex < status.length; ++waiterIndex) {
for (int doorIndex = waiterIndex; doorIndex < status.length; ++doorIndex) {
if (doorIndex % waiterIndex == 0) {
status[doorIndex] = !status[doorIndex];
}
}
}
for (int i = 1; i < status.length; ++i) {
if (status[i]) {
System.out.printf("%-3d : %s\n", i, status[i]);
}
}
}
}
Output:
1 : true--------------------编程问答-------------------- 算上1 奇数个约数的 门开 --------------------编程问答--------------------
4 : true
9 : true
16 : true
25 : true
36 : true
49 : true
64 : true
81 : true
100 : true
public class test01 {
public static void main(String[] args){
boolean isopen[] = new boolean[101] ;
for(int i=0;i<isopen.length;i++){
isopen[i] = false;
}
for(int i=1;i<isopen.length;i++){
isopen[i] = isopen(i);
}
for(int i=1;i<101;i++){
if(isopen[i]) System.out.println(""+i+"="+isopen[i]);
}
}
private static boolean isopen(int i) {
int n=0;
for(int m=1;m<=i;m++)
if(i%m==0) n++;
return n%2==1;
}
}
结果
1=true
4=true
9=true
16=true
25=true
36=true
49=true
64=true
81=true
100=tru[/u]e --------------------编程问答-------------------- 学过算法的人一看就明白了,和开灯问题属于一样的问题,算术运算的妙用。
问题分析:定义100个元素的a数组,他的每个下标变量a[i]视为一个房间。a[i]=1表示门是打开状态,a[i]=0表示门是关闭状态。那么如何实现将第i个房间的门做相反操作呢?马上想到的是用if来表示,但是通过算术运算a[i]=1-[i]可以更好的模拟门的开关操作
伪代码如下:
main(){
int a[100],i,k;
for(i=1;i<=100;i=i+1)
a[i]=0;
for(i=2;i<=100;i=i+1){
k=1;
while(i*k<=100){
a[i*k]=1-a[i*k];
k=k+1;
}
}
for(i=1;i<=100;i=i+1)
if(a[i]=1)
print(i);
}
头一回发帖,献身这个里了.... --------------------编程问答-------------------- public static void main(String[] args) {
List l = new ArrayList();
for (int i = 1; i <= 100; i++) {
for (int j = 2; j <= i; j++) {
if (i % j == 0) {
l.add(i);
}
}
}
System.out.println(l.size());
for(int y=1;y<=100;y++){
int z=0;
for(int x=0;x<l.size();x++){
if(y==Integer.parseInt(l.get(x).toString())){
z++;
}
}
if(z%2==0){
System.out.println(y);
}
}
}
我的思路是,看门被别人摸过几次,加入被摸过的次数能被2正除 说明他满足条件 --------------------编程问答--------------------
public static void main(String[] args){
int[] arr = new int[100];//定义100个房间,arr[i]=0关,arr[i]=1开
for (int i = 0; i < arr.length; i++)
arr[i] = 0;//初始时所有的门都是关闭的
for (int i = 0; i < arr.length; i++) {//服务员编号
for (int j = i; j < arr.length; j=j+1+i) {
arr[j] = 1 - arr[j];
}
}
for (int i = 0; i < arr.length; i++) {
System.out.println("第"+(i+1)+"门:"+arr[i]);
}
}
结果是1~10的平方的房间号的门是开的:1,4,9,16,25,36,49,64,81,100这十个是开的。。。(试过把100改成10一步步调试看结果,发现效果如题所要求的一样,就是不知道改10会不会有问题) --------------------编程问答--------------------
---------------------------------------
本质上分析到位! --------------------编程问答-------------------- 不好意思,eclipse不太好用,C语言写的,算法都一样
#include<stdio.h>
main(){
int i,j,a[1000];
for(i=1;i<=100;i++)
a[i]=0;
for(j=2;j<=100;j++)
{
for(i=1;i<100;i++)
{
if(i%j==0)
{
if(a[i]==0)
a[i]=1;
else
a[i]=0;
}
}
}
for(i=1;i<=100;i++)
{
if(a[i]==0)
printf("%4d \n",i);
}
}
1
4
9
16
25
36
49
64
81
100
--------------------编程问答-------------------- 只是是数是某个数的平方数。那么才会是打开的。
比如说第16个门。那么4号服务员只能打开一次。而除了平方根是同样的数之外,16其他的因数肯定是两两对应的。所以操作抵消。按照这个推论,结果是1234....10这些数的平方的门是打开的。。
如果难以理解可以这样想,100以内所有的数的因数个数是奇数还是偶数,因为门默认是关闭的,只有操作次数是奇数的时候门才是关着的。 --------------------编程问答--------------------
public class Test04 {
public void test(){
int[] door=new int[100];//1打开 0关闭
for(int i=1;i<=100;i++){
for(int j=1;j<=100;j++){
if(i==1){
door[j-1]=1;
}else if(i==2){
if(j%i==0){
door[j-1]=0;
}
}else {
if(j%i==0){
if(door[j-1]==1){
door[j-1]=0;
}else if (door[j-1]==0) {
door[j-1]=1;
}
}
}
}
}
for(int i=1;i<=100;i++){
if(door[i-1]==1){
System.out.println("打开的房间号:"+i);
}
}
}
public static void main(String[] args) {
new Test04().test();
}
}
1
4
9
16
25
36
49
64
81
100
--------------------编程问答-------------------- 考算法的题目都在写代码,可否思考更好的算法呢 --------------------编程问答-------------------- 想一个不和大家一样的思路吧:可以进行因数分解来做这道题目
对应一个门无非就是开/关,两种状态,初始话状态是开着
因此一个门被服务员处理的次数,若为奇数次,门为关;反之,门为开的。
所以问题的焦点就聚集在门被服务员处理几次上,奇数次还是偶数次?
这个不难,
就拿第33个门来说,33=3*11,显然一定后续被两个服务员处理过,那你就错了,别忘了还有33自己,所以第33盏门被服务员处理了3次
现在麻烦来了,刚才举了一个33的例子很好说,
如果遇到32呢?如何分解呢? 32=2*16 ,32=4*8 ,被处理了4+1次,第32个门--》关
(关于如何对第N个门因式分解,先对N求平方根,假设为M,取M的下界,假设为T吧
这里分两种情况了:1、T=M:循环2到T对N进行2元因式分解,计算被整除的次数,整除次数*2-1+1 ,就是被服务员开关门的次数
2、T!=M:循环2到T对N进行2元因式分解,计算被整除的次数,整除次数*2+1 ,就是被服务员开关门的次数
还是用32举例:32的平方根的下界是5,循环2到5,可以被2,4整除,整除次数是2次,2*2+1=5
再举例子64:64平方根正好是8 ,循环2到8,可以被2,4,8整除,整除次数3次,3*2-1+1=6
)
方法效率应该不是很好,但思路不同 --------------------编程问答-------------------- 这题可以认为是1-100的所有数能被1-100内的所有数整除几次
整除次数为奇数的,门开着,整除次数为偶数的,门关上。 --------------------编程问答-------------------- 结果
1
4
9
16
25
36
49
64
81
100
public static void fun(int count, List<Boolean> list){
for(int i = 0; i < list.size(); i++){
if((i+1)%count == 0){
list.set(i, !list.get(i));
}
}
}
public static void main(String[] args) {
List<Boolean> booleans = new ArrayList<Boolean>(100);
for(int i = 0; i < 100; i++){
booleans.add(true);
}
for(int i = 2; i <= 100; i++){
fun(i, booleans);
}
for(int i = 0; i < booleans.size(); i++){
Boolean b = booleans.get(i);
if(b){
System.out.println(i+1);
}
}
}
--------------------编程问答--------------------
public class Demo1 {
public static void main(String[] args) {
remainDoors(1000);
}
private static void remainDoors(int idx){
boolean[] val = new boolean[idx];
for (int i = 1; i <= idx; i++) {
for (int j = 1; j <= idx; j++) {
if(0 == j % i){
val[j-1] = true == val[j-1] ? false : true;
}
}
}
for (int i = 1; i <= idx; i++) {
if(true == val[i - 1]){
System.out.println(i);
}
}
}
}
结果:n^2 --------------------编程问答-------------------- 一个数包含1和它本身在内的因子个数是奇数,门是开的,是偶数,门是关的。
一个数被分解后的形式如下:
p1^k1 * p2^k2 * p3^k3...
p1,p2,p3...是素数
那么包含1在内的因子个数(组合数)为:
(k1+1)*(k2+1)*(k3+1)...
很显然,只有k1,k2,k3...都是偶数的时候,因子个数才会是奇数,门才会是开的。
此时由于k1,k2,k3...都是偶数,这个数必然是一个数的平方,
反之,如果k1,k2,k3...有一个不是偶数,这个数就不可能是一个数的平方,同时它的因子个数必然是偶数。
--------------------编程问答--------------------
:1、T=M:循环2到T对N进行2元因式分解,计算被整除的次数,整除次数*2-1+1 ,就是被服务员开关门的次数
2、T!=M:循环2到T对N进行2元因式分解,计算被整除的次数,整除次数*2+1 ,就是被服务员开关门的次数情况1结果一定为偶数
情况2一定为奇数,所以平方根为整数的门为开,平方根不是整数的门关 --------------------编程问答--------------------
分析的精彩啊 --------------------编程问答-------------------- 求正确解答. --------------------编程问答-------------------- public class test{
public static void main(String[] args){
int[] a = new int[100];
for(int i = 0 ; i < 100 ; i++){
a[i] = 0;
}
for(int i = 1 ; i<=100; i++){
for(int j = 0 ; j<100 ; j++){
if((j+1)%i==0){
a[j] = 1-a[j];
}
}
}
for(int i = 0 ; i<100 ; i++){
if(a[i] == 1){
System.out.println(i+1);
}
}
}
} --------------------编程问答-------------------- 不知道,最前面哪些人在学校是怎么学的,应该算法课的教材上会有这个例子的,上面的算法应该是教材上提供的;标题应该是“利用数组来记录状态”那个地方讲的 记不太清楚了 --------------------编程问答--------------------
精彩而不正确 --------------------编程问答-------------------- 27楼是对的,这题就是求100以内有奇数个约数的数字,一个数分解质因数,q=m^a*n^b*....m,n是质数,那么q的约数有(a+1)(b+1)...要100以内的,那么就只有1,2^2 3^2 5^2 7^2 2^4 3^4 2^2*3^2 2^2*5^2 就这么多,, --------------------编程问答-------------------- 那比如16呢,,能被8打开么。。 --------------------编程问答-------------------- package test;
import java.util.ArrayList;
import java.util.List;
public class TestRoom {
public static void main(String[] args) {
List<Room>rooms=new ArrayList<Room>();
for(int i=1;i<=100;i++){
rooms.add(new Room());
}
for(int i=1;i<100;i++){
for(int j=i;j<rooms.size();j++){
if((j+1)%(i+1)==0){
if(rooms.get(j).isOpen==true){
rooms.get(j).isOpen=false;
}else{
rooms.get(j).isOpen=true;
}
}
}
}
for(int i=0;i<100;i++){
if(rooms.get(i).isOpen==true){
System.out.print(i+1+"\t");
}
}
}
}
class Room{
public boolean isOpen=true;
}
答案是: 1 4 9 16 25 36 49 64 81 100
强烈支持6楼,这就是正确答案,仅作验证
6楼兄弟高屋建瓴,在下拜服 --------------------编程问答--------------------
------------
比如16,它会被第1个(开)和第16个(关),第2个(开)和第8个(关),但只是第4个服务生是找不到另一个因子所构成的乘积是16的(除非是它自己本身:16=4*4,可是第4个已经操作过一次了,不是么?)严重同意6楼大神之高见! --------------------编程问答--------------------
--------------------
比如16,它能被8打开,就能被2关闭。。。。只有4打开,除非4再回来把它关了,不然它就是操作奇数次,当然是开的 --------------------编程问答--------------------
这个是正解吧,分析到位啊 --------------------编程问答-------------------- 除 --------------------编程问答--------------------
import java.io.*;--------------------编程问答-------------------- 6楼说到了
public class OpenShut {
/**
* @param args
* 题目:现有一个酒店有100个房间,依次编号1~100,第一个服务员经过,将所有房门打开;
* 第二个服务员经过将所有编号为2的倍数的房门关上;第三个服务员经过将所有编号为3的倍数的房门
* 打开的关上,关上的打开。第四、五个服务员以此类推,问第100个服务员进来,有哪些门是开的?
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
boolean[] door=new boolean[100];
for(int i=0; i<door.length; i++)
door[i]=false; //false门关,true门开,当然创建数组door时系统默认初始值也是false
for(int i=1; i<100; i++){ //服务员
for(int j=0; j<100; j++){ //门
if((j+1)%i==0)
door[j]=!door[j];
}
}
for(int i=0; i<100; i++){
if(door[i])
System.out.print((i+1)+" ");
}
}
}
是求1~100中具有奇数个因数的所有数
而整数都可以表示为任意两个不同因数的乘积,除了平方数,它可以表示为唯一两个相同因数的乘积,这样也就只有平方数的因数个数是奇数了 --------------------编程问答--------------------
public static void main(String[] args) {我的考虑角度是门。每个门被开了多少次,所以记录下所有从1到100号人开的门是几多,吧它们存到集合中,然后根据集合中每个元素出现的次数假如能被2正除说明满足条件啊,然后输出即可! --------------------编程问答-------------------- 绝对正解
List l = new ArrayList();
for (int i = 1; i <= 100; i++) {
for (int j = 2; j <= i; j++) {
if (i % j == 0) {
l.add(i);}}}
System.out.println(l.size());
for(int y=1;y<=100;y++){
int z=0;
for(int x=0;x<l.size();x++){
if(y==Integer.parseInt(l.get(x).toString())){
z++;}}
if(z%2==0){
System.out.println(y);}}
}
public static void main(String[] args) {
boolean[] b=new boolean[100];
for (int i = 1; i <= 100; i++) { //这里是第一个服务员的做法
b[i-1]=true;
}
for (int i = 2; i <100 ; i++) { //这里循环98次,也就是第2个服务员到第99个服务员的打开门动作
for (int j = i; j < 101; j=j+i) {
if(j%2==0){
b[j-1]=false;
}else{ //只要是奇数就把关着的门打开,把打开的门关闭
if(b[j-1]){
b[j-1]=false;
}else{
b[j-1]=true;
}
}
}
}
for (int i = 0; i < b.length; i++) {
if(b[i]){
System.out.print(i+1+" ");
}
}
}
输出是:1 9 25 49 81
顶6楼的全是易做图!自己仔细想想吧 --------------------编程问答-------------------- 其实楼主没有把问题说明白,第一个把门全打开,第二人把所有二的倍数的门全关,第三个人把所有是3的倍数的门关的开,开的关,那个第4个呢?是把所有4的倍数的门关,还是把4的倍数的门关的开,开的关呢??? --------------------编程问答-------------------- 奇数的平方。
分别找到1-100的因数,例如9的因数有1、3、9,也就是第1、3、9个服务员会改变门的状态。所以最后是打开的。其他数字类似,最后得到奇数的平方数的门是打开的。
也就是,1、9、25、49、81 --------------------编程问答--------------------
应该没有注意到题目中的每次门的状态都会改变。比方说4,因子有1.2.4.这三次使门的状态为开 ,但是还有另外97次要改变状态,奇数次就是关了。所以我觉得是奇数次平方。 --------------------编程问答-------------------- 第N道门满足以下条件为开:
n除以n至1,得到n条表达式,在这n条表达式中没有余数的表达式的数目为奇数,第N道门即为开
public class RoodDemo {
public static void main(String args[]){
for(int i=1;i<100;i++){
int con=0;
for(int j=1;j<=i;j++){
if(i%j==0){
con++;
}
}
if(con%2==1){
System.out.print(i+"、");
}
}
}
}
输出:
1、4、9、16、25、36、49、64、81、 --------------------编程问答--------------------
世上无绝对,孩子。。。四号门,1服务员开,2服务员关,4服务员开,此后无人操作此门。 --------------------编程问答--------------------
public class Test042502 {
public static void main(String[] args) {
Door[] d = new Door[100]; //将所有的房间装在一个Door数组里
for(int i=0;i<d.length;i++) {
d[i] = new Door(i+1,false); //为100个房间赋个初值,让其房号从1~100,默认都关闭
}
for(int wi=1;wi<=100;wi++) { //wi为Waiter Id,1~100个服务员
for(int i=0;i<100;i++) {
if(d[i].fh%wi==0) { //第wi个服务员去开、关门,整除的改变门的状态
if(d[i].con==false) {
d[i].con=true; //关闭的打开
} else {
d[i].con=false; //打开的关闭
}
}
}
}
for(int i=0;i<d.length;i++) {
if(d[i].con==true) { //打印开着的房间的房号
System.out.println(i+1);
}
}
}
}
class Door {
int fh = 1; //门的房号
boolean con= false; //默认门的状态为关闭的
Door(int fh,boolean con) {
this.fh = fh;
this.con = con;
}
}
//运行结果是:1 4 9 16 25 36 48 64 81 100
自学的菜鸟 --------------------编程问答-------------------- 好精妙的思路!能改变门状态的只有编号为房门号因数的服务员,且都是成对出现的(除了平方根)!学习了, --------------------编程问答--------------------
--------------------编程问答-------------------- 出了第1个房间的门是开着的,还有那个房间的门没关. --------------------编程问答--------------------
public class Room {
boolean isOpen = true;
public void changeStatus(){
isOpen = !isOpen;
}
}
public class Test {
public static void main(String[] args) {
List<Room> rooms = new ArrayList<Room>();
/*100 Room*/
for(int i = 1; i < 101; i++){
rooms.add(new Room());
}
/*100 Waiter*/
for(int i = 1; i < 101; i++){
/*100 Door*/
for(int j = 0; j < 100; j++){
if(j%i == 0){
/*Change Status*/
rooms.get(j).changeStatus();
}
}
}
/*Print it*/
for(int i = 0; i < 100; i++){
if(rooms.get(i).isOpen == false){
System.out.println(i);
}
}
}
}
/*Result*/
1
4
9
16
25
36
49
64
81
看漏了半句. --------------------编程问答-------------------- 除
补充:Java , Java SE