约瑟夫环问题 || C++语言 | 小女终于开始学习啦 | 打卡Day1

这里是生物专业的小希,初次见面请多多指教 > <

去年在好朋友的怂恿下稀里糊涂地报名了蓝桥杯,没想到一直拖到寒假才开始学习(真是惭愧)

目前的学习进度是完成了C++的基础知识,(在B站上面学的),真的非常基础,核心编程那块还没有开始,所以做题的方法十分有限 😦

下面有请大家欣赏第一道让我一做就是一天的题~

约瑟夫环

简单版

有n人围成一圈,顺序排号。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来的第几号的那位。

初步思路:一点都没有。讨教了初中二年级的弟弟之后,由衷地敬佩,真不愧是我弟弟。

解题思路

  1. 创建一个很长的数组。
  2. 将里面的前n个元素赋值 1

1 1 1 1 1 1 1

  1. 设置“报数”参数 m=0,“退出”参数 a=n
  2. 开始循环,若遇到 1,则“报数”参数 m++
  3. m 是3的倍数,则将此数组元素赋值 0,同时“退出”参数 a–

1 1 0 1 1 0 1

  1. 一轮循环走完后,再从第一个元素开始第二轮循环,直到 a=1,此时数组里面只有一个元素的值为 1

0 0 0 1 0 0 0

  1. 新建一个循环,找到值为1的元素下标,得到答案。

该思路的优点:让小白觉得耳目一新的地方是“报数”参数 m 的设置,比起绞尽脑汁地去想,怎么让元素退出(不再参与报数)呢,不如让它留在数组内,通过 m 阻止它“报数”。

易错点:后期报数时一定会有两个值为 0 的元素连续出现的情况,这个时候虽然 m 的值并没有变化,但很有可能导致 a– 运行多次(如果此时刚好m为3的倍数),因此需要在 a– 之前加一个判断语句(具体参照代码如下哦)

我的答案

#include<iostream>
using namespace std;

int main()
{
	int n,m=0,i,j;
	cin>>n;
	int a=n,arr[1000]; 
	for(i=0;i<n;i++) arr[i]=1;

	for(i=0;i<n;) 
	{
		if(arr[i]==1) m++;
		if(m%3==0)
		{
			if(arr[i]==1) a--; 
			arr[i]=0; 
		} 
		if(b==1) 
		{
			for(j=0;j<n;j++) 
			{
				if(arr[j]==1)
				{
					cout<<j+1;
					break;
				}
			}
			break;
			
		}
		i++if(i==n) i=0; 
	}
	return 0;
}

后来在网上找其他人的算法的时候还看到了用链表(这个还没学嘿嘿)和递归的办法,递归法写出来的代码只有短短几行,好的!等我脑子清楚的时候把它搞懂,再回来交作业!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值