学生储物柜拼图

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=0i++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;

}