278约瑟夫环

本文详细介绍了如何使用C++编程解决约瑟夫环问题,包括需求分析、概要设计、详细设计和调试过程。程序通过数组实现,核心算法是循环遍历数组并检查密码匹配,当条件满足时更新状态并输出结果。调试过程中注意了密码更新的正确位置,最终实现了程序的正确运行。
摘要由CSDN通过智能技术生成

题目一:278.约瑟夫环

                                         上机报告
                              题目:编写一个和约瑟夫环相关的程序

一、需求分析

1.本演示程序中,需要完成的输入输出全部为整型数,随机数m>0,要求输入第一行为人的个数及初始密码,第二行表示每个人的密码。输出也为一串整型数。编写此题并不需要构建新的数据类型。
2.程序运行只需要在编译器或者cmd界面按照要求输入即可得到输出。
3.程序的命令包括:
1)n,m的输入 2)表示人初始编号的数组a[]的输入 3)按照循环依次输出每次出圈的密码 4)return 0 结束
4.测试数据
(1)输入:
7 20
3 1 7 2 4 8 4
输出:6 1 4 7 2 3 5

二、概要设计

为实现上述程序功能,我们用数组表示所有人的初始编号。
1.所有人的初始编号设为a[100],题目中没有给出最大限制人数,因此我们先开一个大一些的数组。
2.本程序比较简单,只有主程序一个模块。

int main()
{
    //初始化数据设置
    scanf("%d %d",&n,&m);
    scanf("%d ",&a[i]);    //两个输入语句
    while()
    {
        //循环语句
    }
    return 0}

三、详细设计

1.初始数据设置

int a[100];   //表示所有人持有的密码
int n,m;    //n,m表示人的个数和初始密码数
int i;   //循环数
int number;  //当前报的号,用于和每个人的密码相比较
int x;  //记录初始人数

2.核心循环语句(解析在代码段中)

while(x>0) //循环语句的判断条件:圈中还有人
{
	for(i=1;i<=n;i++)
	{
		if(a[i]!=0)
		{
			number++;  //循环到的人编号不为0,给报号加1
		}
		if(number == m)
		{
			m = a[i];  //储存当前人的密码,用于下一次循环
			a[i] = 0;  //将报到的人编号置0
			number = 0; //将计数清0
			x--; //圈中人报到一个就减少一个
			printf("%d ",i);  //输出当前人的密码号
		}
	}
}

3.完整的代码展示:

#include <stdio.h>
int main()
{
	int a[100],n,m,i,number,x;
	number = 0;
	scanf("%d %d",&n,&m);
	x = n;
	for(i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	while(x>0)
	{
		for(i=1;i<=n;i++)
		{
			if(a[i]!=0)
			{
				number++;
			}
			if(number == m)
			{
				m = a[i];
				a[i] = 0;
				number = 0;
				x--;
				printf("%d ",i);
			}
		}
	}
	return 0;
}

四、调试分析

1.本题和部分约瑟夫环不同,需要在每次人出圈后更改下一次出圈的密码,一开始我没注意到这点,按照惯性思维,导致错误,好在及时发现,但是前面几次没有将m = a[i]放到正确的位置,导致只有一个输出程序就停止,纠正后完成程序编写。
2.本题比较容易,没有过多的数据结构的单独编写,使用数组很快的解决了此题,如果使用链表则需要额外编写结构定义。
3.算法的时空分析
1)两条输入语句时间复杂度分别为O(1),O(n),循环while语句中嵌套了for循环,时间复杂度为O(n^2)。

五、用户手册

1.打开程序运行,根据要求输入,按Enter得到输出结果。

六、测试结果

在这里插入图片描述

七、附录

源程序文件名清单:
278约瑟夫环.cpp

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值