约瑟夫环(pta)

题目描述
有n个人围成一圈(编号为1~n),从第1号开始进行1、2、3报数,凡报3者就退出,下一个人又从1开始报数……直到最后只剩下一个人时为止。请问此人原来的位置是多少号?

输入格式:
测试数据有多组,处理到文件尾。每组测试输入一个整数n(5≤n≤100)。

输出格式:
对于每组测试,输出最后剩下那个人的编号。

输入样例:

10
28
69

输出样例:

4
23
68

思路:
约瑟夫环是比较经典的题目,是指n个人站成一排,第一个人和最后一个人手牵着手,(给每个人编号,编号从1到n)然后给定一个步长,按照这个步长开始淘汰人,如果步长是3的话,那就从第一个人开始,数过三个人之后就淘汰掉第三个,然后继续向下走,再次开始从第一个人开始,数三个步长就开始淘汰人,直到剩下最后一个人,要求输出最后一个人的编号。很明显我们可以想到使用队列的方式,假如步长是3,那么我们可以先把队首和队首第二个(小于3即可)

q.push(q.front());
                q.pop();

然后把三个直接出队q.pop();(这里可以嵌套一个循环:)

for(int j=1;j<3;j++){
                q.push(q.front());
                q.pop();
            }

假如步长是3,前两个直接移到队尾,第三个直接出队;这样每隔三个就出队一个,而且保证前两个不会丢失,会直接移位到最后面,等待下次循环的时候再次使用,这也和现实比较相似。在这个循环外面可以再加一个循环,用来遍历队列,这样遍历到最后每次循环都会淘汰一个人,最后只剩下一个人,我们只需要输出队首元素即可。
这个题目也有一些难度,那就是输入的问题,输入的话我们可以使用while(scanf("%d",&n){定义队列并输入队列}来解决。
详细代码如下:

#include<bits/stdc++.h>
using namespace std;
int n;
int main(){
	while(scanf("%d",&n)!=EOF){
		queue<int> q;
		for(int i=1;i<=n;i++){
			q.push(i);//自动添加i从1到n,存储到队列:1 2 3 4 5 6 7...n 
		}
		for(int i=1;i<n;i++){
			for(int j=1;j<3;j++){
				q.push(q.front());
				q.pop();
			}
			q.pop();
		}
		cout<<q.front();
	}
}

运行结果图片:

在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值