C 100 囚犯之谜,我的代码有问题

问题描述 投票:0回答:2

(如果你已经知道谜语是什么,只需阅读最后两行)

我看过一个关于一个谜语的视频,叫做“100个囚犯之谜”,它本质上告诉你一群囚犯(一次只有一个人)进入一个房间,这个房间里有盒子,盒子的顺序从1到a 100 但盒子里的数字是随机的,每个进入房间的囚犯也从 1 到 a 100 编号,所以每个囚犯必须选择有他编号的盒子,每个囚犯都有一组尝试(50 次尝试)如果他打开 50 个盒子但没有找到他的号码,他就输了!例如,1 号囚犯进入房间,他必须找到有他号码的盒子。谁知道可能是 7 号、19 号或 27 号盒子!所以这只是运气游戏..或者是吗?游戏有策略和方法来数学地解决谜题,但这不是我的问题,我只是想用 C 语言编写游戏并自己解决谜题,代码中有很多漏洞,所以仔细研究它并找到它是什么问题,谢谢大家:)!

#include <stdio.h>
#include <stdlib.h>

int main() {
    int i, j = 0, k = 0, counter = 0;
    int boxes[10];
    int boxEntered;
    for (i = 0; i <= 10; i++) \\ numbering the array
        boxes[i] = i;
    for (i = 0; i <= 10; i++) {    
        int temp = boxes[i];
        int randomIndex = (rand() % 10); \\ shuffling the boxes to put random numbers
        boxes[i] = boxes[randomIndex];
        boxes[randomIndex] = temp;
    }
    for (i = 0; i <= 10; i++) {
        printf("%d : (%d)\n", boxes[i], i); \\ print the boxes randomized and their index ordered
    }
    printf("You only have 5 tries!\n");
    while (k != 5) {
        while (j < 10) {
            printf("Pick a box number between 0 and 10 (You are number %d)\n",counter);
            scanf("%d",&boxEntered);
            if (boxes[boxEntered] == boxes[counter]) {
                printf("\nYou succeded, PROCEED TO NEXT PRISONER\n");
                j++; \\ go to the next iteration
                k = 0; \\ set tries back to 0
                counter++; 
            } else
                printf("Try again\nThe box you entered had number %d\n",boxes[boxEntered]);
            k++;
            if (k == 5) { \\ if player prisoner fails 5 times you break the loop
                break;
            }
        }
    }
    if (counter == 10) { \\ if last prisoner was reached successfully then game is won
        printf("You are freed!");
    } else {
        printf("You are going back heheheheheh!\n")
    }
    return 0;
 }

正如您在这张图片中看到的,输出根本没有任何意义,我不知道这里出了什么问题..

arrays c math indexing puzzle
2个回答
1
投票

从你的代码逻辑来看,你应该替换

boxes[boxEntered] == boxes[counter]

boxes[boxEntered] == counter

这是因为这里的

counter
似乎代表着囚犯。拿走
boxes[counter]
会给你一个 box,这不是你想要的;您正在尝试查看该盒子是否与当前囚犯匹配。

另一个重要注意事项是以下代码将超出数组范围,导致未定义的行为:

for (i = 0; i <= 10; i++) boxes[i] = i;

boxes
被声明为具有大小
10
,因此采用
boxes[10]
会出界;最大为
boxes[9]

要解决此问题,您可以从

1
开始索引数组。要在
C
中执行此操作,请使用
boxes[10]
,而不是声明
boxes[11]
。这将确保您可以访问
boxes[10]

然后您可以将循环更改为从

1
开始,例如:

for (i = 1; i <= 10; i++) boxes[i] = i;

请务必对代码中的每个数组和 for 循环进行此更改。


-1
投票

说实话我还没有读过你的代码。只是使用单字符变量名是我的一个小烦恼(无意冒犯你)。不管怎样,我目前正在写一本关于 C 编程语言的初学者书籍。以下程序(用 C 语言编写)可以模拟 100 名囚犯问题。该程序执行 1000 次试验,然后最终产生结果输出(成功率百分比)。

// This program simulates the 100 prisoner problem.
#include <stdio.h>
#include <stdlib.h>
#include <time.h.>

    int boxNumber[100] = {0};//Declaring global integer array (100 "boxes" from 0 to 
                             //99).
    
    float flag=0.0; //Declaring global variable for keeping track of success rate.
    
    void seedRandom(); //Seeds the srand() function with current time.
    void writeNegative();//Fills entire global integer array with -1.
    void writeValue();//Writes values into each "box" (integer array).
    void prisoners(); //Prisoners check each box.
    void loop(); //Runs program for 1000 trials (should yield about 31 percent success rate).
    
    int main()
    {
    int cntr;
    
    seedRandom();
    loop();
    
    printf("\n\nThere was a %.0f percent success rate.\n\n", flag/1000*100);
    
    return 0;
    }
    //-------------------------------------------------------------------------------------
    void loop()
    {
    int cntr;
    for (cntr=0;cntr<1000;cntr++)
      {
      writeNegative();
      writeValue();
      prisoners();
      }
    }
    //-------------------------------------------------------------------------------------
    void seedRandom()
    {
    time_t now;//Declaring time-type variable.
    time(&now);//Storing system time into now.
    srand(now);//Seeding the random number generator with system time.
    }
    //-------------------------------------------------------------------------------------
    void writeNegative()
    {
    int cntr;
    for (cntr=0;cntr<100;cntr++)//Writing -1 into each array subscript.
       { boxNumber[cntr]=-1; }
    }
    //-------------------------------------------------------------------------------------
    void writeValue()
    {
    int cntr=0; //Used for writing a value into each of the 100 "boxes"
                //starting with 0.
    int select; //Used to randomly select a box.
    while (cntr<100)//Writes a value into each box.
      {
      select=rand()%100;//Writing random number into select (must be less than 100).
      if (boxNumber[select]==-1) //Selects a box randomly. We only want to
        {             //write into a box that hasn't been filled yet.
        boxNumber[select]=cntr;  //Writing value into box.
        cntr++;  //Incrementing to next value.
        }
      }
    }
    //-------------------------------------------------------------------------------------
    void prisoners()
    {
    int cntr; //Counts 50 chances for prisoner to check boxes.
    int psnr; //Indicates prisoner number.
    int currentBox; //
    int success=0;
    for (psnr=0;psnr<100;psnr++)
       {
       currentBox=psnr;//Prisoner starts with his box number.
       for (cntr=0;cntr<50;cntr++)//Prisoner gets 50 chances.
         {
         if(boxNumber[currentBox]==psnr)//Prisoner starts with his box number.
           {
           printf("Success! Prisoner %d = box %d\n",psnr,currentBox);
           success++;
           break;//Breaks current loop & moves onto next prisoner.
           }
           else
             { currentBox=boxNumber[currentBox]; }//Prisoner goes to box number that
         }                      //was written inside previous box.
       }
    if (success==100)
       { printf("Congratulations! All the prisoners have made it.\n\n");
    flag=flag+1.0; //Counts number of successes.
      }
    
       else
         { printf("Only %d were successful.\n\n",success); }
    }
© www.soinside.com 2019 - 2024. All rights reserved.