学生储物柜拼图
Student Locker puzzle
/* 学生100人,储物柜100个。学生 1 全部打开,学生 2 每秒钟关闭一次,学生 3 每三分之一更改一次
储物柜(如果打开则关闭,如果关闭则打开),学生 4 每隔四个储物柜更换一次,依此类推所有 100 名学生。
哪个储物柜将保持打开状态? */
到目前为止,这是我的代码:
#include <stdio.h>
int main(void)
{
int locker[100], i, closed = 0, opened = 0;
for(i=0; i<100; i++) locker[i] = 1;//0 means closed locker, 1 means open locker
for(i=1; i<101; i++) if(i % 2 == 0) locker[i-1] = 0; // every second locker is closed by second student...(2,4,6,7)
for(i=3; i<101; i++){ // i means student no. i
if(locker[i-1] == 0) locker[i-1] = 1;
if(locker[i-1] == 1) locker[i-1] = 0;
如果我用 "else" 替换 "if(locker[i-1] == 1)" 为什么程序不起作用?正确的结果是opened 1 closed 99.如果我用'else'结果变成opened 50 and closed 50
}
for(i=0; i<100; i++){
if(locker[i] == 0) closed = closed + 1;
else opened = opened + 1;
}
printf("opened locker %d\nclosed locker %d", opened, closed);
return 0;
}
这是我在堆栈溢出中的第一个 post。如果我做错了什么,请纠正我。
虽然我没有检查完整的代码,而且我对你的问题的逻辑不是很清楚,但这些行在你的代码中似乎是有问题的:
if(locker[i-1] == 0) locker[i-1] = 1;
if(locker[i-1] == 1) locker[i-1] = 0;
你在这里做的是,如果一个值是 0,那么你将它设置为 1,然后你再次检查,如果它是 1,你将它设置为 0。所以,所以在这种情况下通过这两个语句 运行 之后,所有值都将设置为 0。
相反,你应该这样做
if(locker[i-1] == 0) locker[i-1] = 1;
else locker[i-1] = 0;
请注意,您的循环是错误的,因为您正在循环第三个学生的每个储物柜,而不是循环剩余的储物柜。您应该为每个学生 (n) 将第 n 个储物柜换成相反的。
当你连续有两个 if 时。如果第一个 if 打开储物柜,第二个 if 看到它打开并关闭它(这是错误的)。需要 else 才能实际更改它。
还有一点就是可以用exclusive or代替if locker[i] ^= 1
#include <stdio.h>
int main(void)
{
int locker[100], i, k, closed = 0, opened = 0;
for(i=0; i<100; i++) {
if (i%2 == 0) locker[i] = 1; // odd lockers (base 1) stay open
else locker[i] = 0; // even lockers (base 1) are closed
//0 means closed locker, 1 means open locker
for(i=3; i<101; i++){ // i means student no. i
for (k=i; k<101); k+=i) { // change every ith locker
// if (locker[k-1] == 0) locker[k-1]=1
// else locker[i-1] = 0;
// use exclusive or instead of if
locker[i-1] ^= 1;
}
}
}
// Now check the number open or closed
for(i=0; i<100; i++){
if(locker[i] == 0) closed = closed + 1;
else opened = opened + 1;
}
printf("opened locker %d\nclosed locker %d", opened, closed);
return 0;
}
我会给你一些提示来帮助你。
- 答案是 10 个储物柜保持打开状态,90 个关闭。
- 对于这个特定问题,如果避免从零开始的索引,编写代码会更容易。所以
将数组声明为
int locker[101];
然后使用索引 1 到
100代表100个储物柜。
- 第 N 个学生应该更换第 N 个储物柜。所以你需要
两个嵌套的
for
循环。外循环跟踪 n
,而
内循环翻转储物柜。
只影响第 N 个储物柜的内部循环应该是这样的
这个
for ( i = n; i <= 100; i += n ) // every Nth locker
locker[i] = 1 - locker[i]; // flip the locker
请注意,我们有 i=n
而不是正常的 i=0
和 i++
和 i+=n
。因此,例如,如果 n
为 3,则 i
的值
是 3,6,9,...
LOCKERS 是新的 FIZZBUZZ。
您已经对这个问题有了很好的答案。这是一个使用布尔值的小程序。
/* lockers.c
There are 100 students and 100 lockers. Student 1 opens all, student 2
closes every second one, student 3 changes every third locker (closes if
open, opens if close), Student 4 changes every forth locker and so on for
all 100 students. Which lockers will be open at the end of the process?
*/
#include <stdio.h>
#include <stdbool.h>
int main (void)
{
int i, j;
bool locker[101]; // locker open = true, locker closed = false
// student 1 opens all lockers
for ( i = 1; i <= 100; ++i )
locker[i] = true;
// subsequent students toggle subsequent lockers
for ( i = 2; i <= 100; ++i )
for ( j = i; j <= 100; j += i )
locker[j] = ! locker[j];
// display results
printf ("\nopen lockers: ");
for ( i = 1; i <= 100; ++i )
if ( locker[i] )
printf ("%i ", i);
printf ("\n");
return 0;
}
打开的储物柜是完全平方数——任何具有奇数个因数的数字都是完全平方数。
不使用数组的解决方案。
#include <iostream>
using namespace std;
int main()
{
int studentTotal , lockerTotal, visit, totalOpened = 0, totalClosed = 0;
cout << "Enter number of students" << endl;
cin >> studentTotal;
lockerTotal = studentTotal;
for (int locker = 1; locker <= lockerTotal; locker++ ){ // locker loop
cout << "\n\n\nLocker no." << locker << endl;
cout << " is visited by student(s) ";
visit = 0;
for (int student = 1 ; student <= studentTotal; student++) { // student loop
if( locker % student == 0) {
cout << student << ", ";
visit++;}
}//end of locker loop
cout << "\nTotal number of visits: " << visit;
if (visit % 2 == 0){
cout << " the locker will stay closed.";
totalClosed++;}
else { cout << " the locker will be opened.";
totalOpened++;}
} //end of student loop
if (lockerTotal == totalOpened + totalClosed) {
cout << "\n\n\nOf total lockers (" << lockerTotal << "), " << totalOpened << " will be left open." << "(" << totalClosed << ") " << "will be closed." << endl;
}else cout << "Error!!";
return 0;
}
/* 学生100人,储物柜100个。学生 1 全部打开,学生 2 每秒钟关闭一次,学生 3 每三分之一更改一次 储物柜(如果打开则关闭,如果关闭则打开),学生 4 每隔四个储物柜更换一次,依此类推所有 100 名学生。 哪个储物柜将保持打开状态? */
到目前为止,这是我的代码:
#include <stdio.h>
int main(void)
{
int locker[100], i, closed = 0, opened = 0;
for(i=0; i<100; i++) locker[i] = 1;//0 means closed locker, 1 means open locker
for(i=1; i<101; i++) if(i % 2 == 0) locker[i-1] = 0; // every second locker is closed by second student...(2,4,6,7)
for(i=3; i<101; i++){ // i means student no. i
if(locker[i-1] == 0) locker[i-1] = 1;
if(locker[i-1] == 1) locker[i-1] = 0;
如果我用 "else" 替换 "if(locker[i-1] == 1)" 为什么程序不起作用?正确的结果是opened 1 closed 99.如果我用'else'结果变成opened 50 and closed 50
}
for(i=0; i<100; i++){
if(locker[i] == 0) closed = closed + 1;
else opened = opened + 1;
}
printf("opened locker %d\nclosed locker %d", opened, closed);
return 0;
}
这是我在堆栈溢出中的第一个 post。如果我做错了什么,请纠正我。
虽然我没有检查完整的代码,而且我对你的问题的逻辑不是很清楚,但这些行在你的代码中似乎是有问题的:
if(locker[i-1] == 0) locker[i-1] = 1;
if(locker[i-1] == 1) locker[i-1] = 0;
你在这里做的是,如果一个值是 0,那么你将它设置为 1,然后你再次检查,如果它是 1,你将它设置为 0。所以,所以在这种情况下通过这两个语句 运行 之后,所有值都将设置为 0。
相反,你应该这样做
if(locker[i-1] == 0) locker[i-1] = 1;
else locker[i-1] = 0;
请注意,您的循环是错误的,因为您正在循环第三个学生的每个储物柜,而不是循环剩余的储物柜。您应该为每个学生 (n) 将第 n 个储物柜换成相反的。
当你连续有两个 if 时。如果第一个 if 打开储物柜,第二个 if 看到它打开并关闭它(这是错误的)。需要 else 才能实际更改它。
还有一点就是可以用exclusive or代替if locker[i] ^= 1
#include <stdio.h>
int main(void)
{
int locker[100], i, k, closed = 0, opened = 0;
for(i=0; i<100; i++) {
if (i%2 == 0) locker[i] = 1; // odd lockers (base 1) stay open
else locker[i] = 0; // even lockers (base 1) are closed
//0 means closed locker, 1 means open locker
for(i=3; i<101; i++){ // i means student no. i
for (k=i; k<101); k+=i) { // change every ith locker
// if (locker[k-1] == 0) locker[k-1]=1
// else locker[i-1] = 0;
// use exclusive or instead of if
locker[i-1] ^= 1;
}
}
}
// Now check the number open or closed
for(i=0; i<100; i++){
if(locker[i] == 0) closed = closed + 1;
else opened = opened + 1;
}
printf("opened locker %d\nclosed locker %d", opened, closed);
return 0;
}
我会给你一些提示来帮助你。
- 答案是 10 个储物柜保持打开状态,90 个关闭。
- 对于这个特定问题,如果避免从零开始的索引,编写代码会更容易。所以
将数组声明为
int locker[101];
然后使用索引 1 到 100代表100个储物柜。 - 第 N 个学生应该更换第 N 个储物柜。所以你需要
两个嵌套的
for
循环。外循环跟踪n
,而 内循环翻转储物柜。 只影响第 N 个储物柜的内部循环应该是这样的 这个
for ( i = n; i <= 100; i += n ) // every Nth locker locker[i] = 1 - locker[i]; // flip the locker
请注意,我们有
i=n
而不是正常的i=0
和i++
和i+=n
。因此,例如,如果n
为 3,则i
的值 是3,6,9,...
LOCKERS 是新的 FIZZBUZZ。
您已经对这个问题有了很好的答案。这是一个使用布尔值的小程序。
/* lockers.c
There are 100 students and 100 lockers. Student 1 opens all, student 2
closes every second one, student 3 changes every third locker (closes if
open, opens if close), Student 4 changes every forth locker and so on for
all 100 students. Which lockers will be open at the end of the process?
*/
#include <stdio.h>
#include <stdbool.h>
int main (void)
{
int i, j;
bool locker[101]; // locker open = true, locker closed = false
// student 1 opens all lockers
for ( i = 1; i <= 100; ++i )
locker[i] = true;
// subsequent students toggle subsequent lockers
for ( i = 2; i <= 100; ++i )
for ( j = i; j <= 100; j += i )
locker[j] = ! locker[j];
// display results
printf ("\nopen lockers: ");
for ( i = 1; i <= 100; ++i )
if ( locker[i] )
printf ("%i ", i);
printf ("\n");
return 0;
}
打开的储物柜是完全平方数——任何具有奇数个因数的数字都是完全平方数。
不使用数组的解决方案。
#include <iostream>
using namespace std;
int main()
{
int studentTotal , lockerTotal, visit, totalOpened = 0, totalClosed = 0;
cout << "Enter number of students" << endl;
cin >> studentTotal;
lockerTotal = studentTotal;
for (int locker = 1; locker <= lockerTotal; locker++ ){ // locker loop
cout << "\n\n\nLocker no." << locker << endl;
cout << " is visited by student(s) ";
visit = 0;
for (int student = 1 ; student <= studentTotal; student++) { // student loop
if( locker % student == 0) {
cout << student << ", ";
visit++;}
}//end of locker loop
cout << "\nTotal number of visits: " << visit;
if (visit % 2 == 0){
cout << " the locker will stay closed.";
totalClosed++;}
else { cout << " the locker will be opened.";
totalOpened++;}
} //end of student loop
if (lockerTotal == totalOpened + totalClosed) {
cout << "\n\n\nOf total lockers (" << lockerTotal << "), " << totalOpened << " will be left open." << "(" << totalClosed << ") " << "will be closed." << endl;
}else cout << "Error!!";
return 0;
}