首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >学生锁定问题(需要数组内的交替)

学生锁定问题(需要数组内的交替)
EN

Stack Overflow用户
提问于 2019-10-23 00:30:14
回答 1查看 226关注 0票数 1

我必须解决这个问题:

A学校有100个储物柜和100个学生。学生1打开所有的储物柜。学生2从第一个开始每第二个储物柜切换一次。学生3开关每第三个储物柜,从后面开始(100)。这条路一直通到第二个学生那里。(从后面或前面开始交替)。

我得在最后展示开着的储物柜。我似乎想不出如何使交替的需求发挥作用。以下是目前为止的代码:

代码语言:javascript
复制
#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;
}
EN

回答 1

Stack Overflow用户

发布于 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,而大于或等于零切换储物柜。

如果您编写了一个简单的切换锁函数,它可能有助于简化事情。

代码语言:javascript
复制
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。因此,对于您的主要逻辑,您可以使用类似于:

代码语言:javascript
复制
    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 ),您可以做类似的事情:

代码语言:javascript
复制
#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;
}

示例使用/输出

以网格形式输出储物柜的最终状态(您可以任意选择)

代码语言:javascript
复制
$ ../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名,您将拥有:

代码语言:javascript
复制
            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 */

因此:

代码语言:javascript
复制
$ ./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]

仔细考虑一下,如果你还有其他问题,请告诉我。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58513913

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档