信息奥赛课课通(C++)p165-3约瑟夫的新问题。

版权声明:如果是我原创的文章,请转载时,注明是来自我的转帖,加上我帖子的地址。谢谢! https://blog.csdn.net/mengdicfm/article/details/82767337

问题描述:
将1-M这M个自然数按由小到大的顺序沿顺时针方向围城一圈。以S为起点,先沿顺时针方向数到第N个数就出圈,然后再沿逆时针方向数到第K个数再出圈,再沿顺时针方向数到第N个数就出圈,然后再沿逆时针方向数到第K个数再出圈……这样按顺时针方向和逆时针方向不断出圈,直到全部数都出圈为止。
请打印先后出圈的数的序列。
输入格式:
4行,每行一个自然数,分别表示M,S,N,K,值都不超过1000.
输出格式:
一行包含N个正整数,之间用一个空格隔开,表示先后出圈的数的序列。
输入样例:
8
1
3
2
输出样例:
3 1 5 2 7 4 6 8

#include<iostream>
#include<cmath>
using namespace std;
int p[1001];
int main(){
    int m,s,n,k,i,last,flag=1,start,count=0;
    cin>>m>>s>>n>>k;
    last=m;
    start=s;
    for(i=1;i<=m;i++)
    p[i]=1;
    //开始所有人都在圈内 
    while(last)
	{
		if(flag==1) //flag=1表示顺时针方向 
		{
			for(i=start;i<=m;i++)
			{
			if(p[i]) //第i个人还未出圈 
				{
					count++;
					if(count%n==0)
					{
						p[i]=0;
						cout<<i<<" ";
						count=0;
						flag=0;
						start=i-1;
						last--;
						break;
					}
					//顺时针数到n时,输出当前的数字i,报数变为0,
					//顺时针变逆时针,下一个报数的人为i-1,剩余人数-1 
				}
			if(i==m)
			i=0;
			//如果已经到了第m个数字,要从第一个数字开始数		
			}
				
		}
		if(flag==0) //flag=0 表示逆时针方向 
		{
			for(i=start;i>=1;i--)
			{
			if(p[i]) //第i个人还未出圈 
				{
					count++;
					if(count%k==0)
					{
						p[i]=0;
						cout<<i<<" ";
						count=0;
						flag=1;
						start=i+1;
						last--;
						break;
					}
					//逆时针数到k时,输出当前的数字i,报数变为0,
					//逆时针变顺时针,下一个报数的人为i+1,剩余人数-1 
				}
			if(i==1)
			i=m+1;		
			//如果已经到了第1数字,要从第m个数字开始数
			}
				
		}
		
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/mengdicfm/article/details/82767337
今日推荐