随机走步问题

一、题目简介

        以下在x-y坐标系上进行的游戏属于二维的随机行走。从原点(0,0)开始,每次迭代都是由向左、向上、向右和向下一个单位的随机步构成。当行走者返回原始点时,行走结束。在二维世界这种情况发生的概率为1,而在三维世界概率小于1。请编写一个进行100次独立随机行走程序,并计算每个方向的步数的平均数。

二、数据结构设计

        在这段代码中,主要使用了以下数据结构:

二维数组 steps[MAX_STEPS][2]:

        用途:存储每次行走的步数和方向。

        结构:steps[i][0] 存储第 i 步的方向,steps[i][1] 存储第 i 步的步数。

整数变量 direction:

        用途:在 randomWalk 函数中,表示行走者当前的行进方向。

整数变量 x 和 y:

        用途:在 randomWalk 函数中,表示行走者当前的位置坐标。

常量定义 LEFT、UP、RIGHT、DOWN、MAX_STEPS:

        用途:定义了方向和最大步数的常量,增加了代码的可读性和可维护性。

函数 randomStep():

        用途:生成一个随机步数,表示行走者的下一步行进方向。

        整体设计思路是,通过使用二维数组 steps 记录每一步的方向和步数,实现对随机行走的模拟。在每次模拟中,通过循环调用 randomWalk 函数来生成随机步数并更新行走者的位置,然后统计每个方向的步数。最后,主函数循环运行多次模拟,打印每次模拟的结果。

        需要注意的是,随机行走的过程中,如果行走者回到原点 (0,0),则会提前终止当前次模拟。这个终止条件在 randomWalk 函数中实现。

三、算法设计

        实现一个随机行走的模拟器,模拟器在一个二维平面上进行随机步行,并统计每个方向上的步数。以下是对代码的算法设计的分析:

(1)随机步生成: randomStep 函数

        生成一个随机的步数,用来表示行走的方向。通过使用 rand() % 4 来生成一个介于0到3之间的随机整数,分别代表左、上、右和下四个方向。

// 生成一个随机步
int randomStep() {
    return rand() % 4;
}

(2)随机行走: randomWalk 函数

        实现了在二维平面上的随机行走。在每一步中,通过调用 randomStep 来获取一个随机方向,记录下该步的方向和步数,并更新当前位置。

// 进行随机行走
void randomWalk(int steps[][2], int numSteps) {
    // 初始化起始位置
    int x = 0, y = 0;
    // 执行随机行走
    for (int i = 0; i < numSteps; i++) {
        int direction = randomStep();
        // 记录步数和方向
        steps[i][0] = direction;  // 记录方向
        steps[i][1] = 1;          // 记录步数
        // 更新位置
        switch (direction) {
            case LEFT:
                x--;
                break;
            case UP:
                y++;
                break;
            case RIGHT:
                x++;
                break;
            case DOWN:
                y--;
                break;
        }
        if (x == 0 && y == 0) break;  // 如果回到原点,提前结束行走
    }
}

(3)模拟器主程序: main 函数

        使用 randomWalk 函数进行100次独立的随机行走,并统计每个方向上的步数。最后,打印每次模拟的结果。

int main() {
    for (int i = 0; i < 100; i++) {
        randomWalk(steps, MAX_STEPS);
        // 计算每个方向的步数
        // ...
        // 打印结果
        // ...
    }
    return 0;
}

(4)统计结果:

        在每次模拟结束后,通过遍历 steps 数组,统计每个方向的步数,并打印输出结果。

// 计算每个方向的步数
int leftSteps = 0, upSteps = 0, rightSteps = 0, downSteps = 0;
for (int j = 0; j < MAX_STEPS; j++) {
    switch (steps[j][0]) {
        case LEFT:
            leftSteps++;
            break;
        case UP:
            upSteps++;
            break;
        case RIGHT:
            rightSteps++;
            break;
        case DOWN:
            downSteps++;
            break;
    }
}

// 打印结果
printf("Simulation %d:\n", i + 1);
printf("Left: %d steps\n", leftSteps);
printf("Up: %d steps\n", upSteps);
printf("Right: %d steps\n", rightSteps);
printf("Down: %d steps\n", downSteps);
printf("\n");

        总体上,这段代码使用了伪随机数生成器 rand 来模拟随机行走,记录每步的方向和步数,并通过统计得到每个方向上的步数。每次模拟的结果包括左、上、右、下四个方向的步数。

四、算法时间复杂度分析

        在这个算法中,最主要的循环是在主函数中进行的,其中包含了循环100次模拟,每次模拟都会执行循环最大步数MAX_STEPS。

主函数中的循环:

        外层循环运行100次,对于每次循环,会执行内层循环 MAX_STEPS 次。

        时间复杂度:O(100 * MAX_STEPS) = O(MAX_STEPS)

randomWalk 函数:

        randomWalk 函数中的循环执行 MAX_STEPS 次。内部没有其他循环或递归,仅有常数时间的操作。

        时间复杂度:O(MAX_STEPS)

randomStep 函数:

        randomStep 函数中只包含一次取余运算和返回操作,是常数时间的操作。

        时间复杂度:O(1)

        综上所述,整个算法的时间复杂度主要由主函数中的循环决定,即O(MAX_STEPS)。值得注意的是,这里假设 randomStep 函数的执行时间是常数,但如果 rand() 函数的实现不是常数时间的话,可能会对时间复杂度产生影响。

五、程序代码

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

// 定义方向常量
#define LEFT 0
#define UP 1
#define RIGHT 2
#define DOWN 3

// 定义最大步数
#define MAX_STEPS 100

// 函数声明
int randomStep();
void randomWalk(int steps[][2], int numSteps);

int main() {
    // 种子初始化
    srand(time(NULL));

    // 存储每次行走的步数
    int steps[MAX_STEPS][2];

    // 进行100次独立随机行走
    for (int i = 0; i < 100; i++) {
        randomWalk(steps, MAX_STEPS);
        
        // 计算每个方向的步数
        int leftSteps = 0, upSteps = 0, rightSteps = 0, downSteps = 0;
        for (int j = 0; j < MAX_STEPS; j++) {
            switch (steps[j][0]) {
                case LEFT:
                    leftSteps++;
                    break;
                case UP:
                    upSteps++;
                    break;
                case RIGHT:
                    rightSteps++;
                    break;
                case DOWN:
                    downSteps++;
                    break;
            }
        }

        // 打印结果
        printf("Simulation %d:\n", i + 1);
        printf("Left: %d steps\n", leftSteps);
        printf("Up: %d steps\n", upSteps);
        printf("Right: %d steps\n", rightSteps);
        printf("Down: %d steps\n", downSteps);
        printf("\n");
    }

    return 0;
}

// 生成一个随机步
int randomStep() {
    return rand() % 4;
}

// 进行随机行走
void randomWalk(int steps[][2], int numSteps) {
    // 初始化起始位置
    int x = 0, y = 0;

    // 执行随机行走
    for (int i = 0; i < numSteps; i++) {
        int direction = randomStep();

        // 记录步数和方向
        steps[i][0] = direction;  // 记录方向
        steps[i][1] = 1;          // 记录步数

        // 更新位置
        switch (direction) {
            case LEFT:
                x--;
                break;
            case UP:
                y++;
                break;
            case RIGHT:
                x++;
                break;
            case DOWN:
                y--;
                break;
        }
        if(x==0&&y==0) break; 
    }
}

  • 11
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jc.MJ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值