我必须解决这个问题:
A学校有100个储物柜和100个学生。学生1打开所有的储物柜。学生2从第一个开始每第二个储物柜切换一次。学生3开关每第三个储物柜,从后面开始(100)。这条路一直通到第二个学生那里。(从后面或前面开始交替)。
我得在最后展示开着的储物柜。我似乎想不出如何使交替的需求发挥作用。以下是目前为止的代码:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_LOCKERS 100
#define MAX_STUDENTS 100
int main (void)
{
int i, n;
bool locker[MAX_LOCKERS + 1];
for ( i = 1; i <= 100; ++i )
locker[i] = true;
for ( i = 2; i <= 100; ++i )
for ( n = i; n <= 100; n += i )
locker[n] = ! locker[n];
if ( locker[i] )
printf ("%i ", i);
printf ("\nThe open lockers are: ");
for ( i = 1; i <= 100; ++i )
if ( locker[i] )
printf ("%i ", i);
return 0;
}发布于 2019-10-23 01:51:41
这是一个有趣的问题,应该取决于奇数/偶数,决定是从开始工作到结束,还是从结束到开始,通过所有学生打开柜门。
当您将元素数(例如for ( i = 1; i <= 100; ++i ))与数组索引(例如for (i = 0; i < 100; i++))混合时,您会感到非常困惑。最好记住数组在C中是零索引的,并且在循环限制循环0 -> n-1而不是1 -> n中保持一致。
(注意:当然都是合法的,但使用实际的索引消除了在循环1 -> n时无法调整索引的与隔离的数组边界的可能性)
(编辑-注:i在循环增量上被逐个关闭-固定)
设置所有储物柜打开后的基本方法是循环使用实际的剩余学生索引,循环1 -> n-1。如果当前的学生是奇数,那么从一开始一直工作到结束切换储物柜。如果当前的学生是,那么即使是,也可以用当前值的倍数(例如,整数除法的end = (100 / current) * current) )来计算可以达到的最后一个索引。(你可能需要end = 100 - (current+1);,这取决于你是否想从学生3开始第三名,等等)现在循环从end,而大于或等于零切换储物柜。
如果您编写了一个简单的切换锁函数,它可能有助于简化事情。
void toggle (int *locker, int idx)
{
if (locker[idx]) /* if locker open */
locker[idx] = 0; /* close it */
else /* otherwise */
locker[idx] = 1; /* open it */
}然后,避免重复代码的主逻辑中的条件。您的代码使用bool,这很好,但我通常只使用int。因此,对于您的主要逻辑,您可以使用类似于:
int i, j;
int locker[MAX_LOCKERS + 1];
for (i = 0; i < 100; i++) /* open all lockers */
locker[i] = 1;
for (i = 1; i < 100; i++) { /* loop all other students */
if (i % 2 == 1) /* odd, from start */
for (j = i; j < 100; j += (i+1)) /* loop j=i , j += (i+1) */
toggle (locker, j); /* toggle lockers at j */
else { /* if even index */
int end = (100 / i) * i; /* get end index by i */
for (j = end; j >= 0; j -= (i+1)) /* from end, loop j -= (i+1) */
toggle (locker, j); /* toggle lockers at j */
}
}总之,(并让您在代码中使用MAX_STUDENTS代替100 ),您可以做类似的事情:
#include <stdio.h>
#include <stdlib.h>
#define MAX_LOCKERS 100
#define MAX_STUDENTS 100
void toggle (int *locker, int idx)
{
if (locker[idx]) /* if locker open */
locker[idx] = 0; /* close it */
else /* otherwise */
locker[idx] = 1; /* open it */
}
int main (void)
{
int i, j;
int locker[MAX_LOCKERS + 1];
for (i = 0; i < 100; i++) /* open all lockers */
locker[i] = 1;
for (i = 1; i < 100; i++) { /* loop all other students */
if (i % 2 == 1) /* odd, from start */
for (j = i; j < 100; j += (i+1)) /* loop j=i , j += (i+1) */
toggle (locker, j); /* toggle lockers at j */
else { /* if even index */
int end = (100 / i) * i; /* get end index by i */
for (j = end; j >= 0; j -= (i+1)) /* from end, loop j -= (i+1) */
toggle (locker, j); /* toggle lockers at j */
}
}
for (i = 0; i < 100; i++) { /* output results in grid form */
if (i && i % 10 == 0)
putchar ('\n');
printf (" %s", locker[i] ? "[x]" : "[ ]");
}
putchar ('\n');
return 0;
}示例使用/输出
以网格形式输出储物柜的最终状态(您可以任意选择)
$ ../bin/openlockers2
[ ] [ ] [x] [x] [ ] [ ] [ ] [x] [ ] [x]
[x] [ ] [x] [ ] [ ] [x] [x] [ ] [ ] [ ]
[ ] [ ] [ ] [x] [x] [x] [x] [x] [ ] [x]
[x] [ ] [x] [x] [x] [x] [x] [ ] [ ] [ ]
[ ] [ ] [x] [x] [ ] [x] [x] [x] [x] [ ]
[ ] [x] [ ] [ ] [x] [ ] [x] [ ] [ ] [ ]
[ ] [x] [x] [ ] [x] [x] [ ] [x] [x] [ ]
[x] [ ] [x] [ ] [ ] [x] [ ] [x] [x] [ ]
[ ] [x] [ ] [x] [ ] [x] [ ] [ ] [x] [x]
[x] [ ] [x] [x] [x] [ ] [x] [x] [x] [x][x] -储物柜打开。(如果这对你来说更有意义的话,你可能想交换一下)
注意:,这是为了展示一种方法来处理您的学生向前或向后工作,通过剩余的学生人数。我还没有花时间来验证逻辑是否正确.我怀疑它是(或非常接近),但是正确性的最终验证由您来完成。
如果使用end的替代定义,例如,从第3名学生开始切换到第3名,您将拥有:
int end = 100 - (i+1);
for (j = end; j >= 0; j -= (i+1)) /* from end, loop j -= (i+1) */
toggle (locker, j); /* toggle lockers at j */因此:
$ ./bin/openlockers2
[x] [x] [x] [ ] [ ] [ ] [ ] [x] [ ] [ ]
[ ] [ ] [ ] [ ] [ ] [ ] [ ] [x] [ ] [x]
[ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [x] [ ]
[ ] [x] [ ] [ ] [ ] [ ] [x] [ ] [ ] [ ]
[ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [x]
[x] [x] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ]
[ ] [ ] [ ] [ ] [x] [ ] [ ] [ ] [x] [ ]
[ ] [x] [ ] [ ] [ ] [x] [ ] [ ] [ ] [ ]
[ ] [ ] [x] [ ] [x] [ ] [ ] [ ] [ ] [ ]
[ ] [x] [x] [ ] [ ] [ ] [x] [x] [x] [x]仔细考虑一下,如果你还有其他问题,请告诉我。
https://stackoverflow.com/questions/58513913
复制相似问题