【基础】约瑟夫问题
题目描述有M个人,其编号分别为1-M。这M个人按顺序排成一个圈。现在给定一个数N,从第一个人开始依次报数,数到N的人出列,然后又从下一个人开始又从1开始依次报数,数到N的...
题目描述
有M个人,其编号分别为1-M。这M个人按顺序排成一个圈。现在给定一个数N,从第一个人开始依次报数,数到N的人出列,然后又从下一个人开始又从1开始依次报数,数到N的人又出列...如此循环,直到最后一个人出列为止。
输入
输入只有一行,包括2个整数M(8 <= M <= 15 ),N( 5 <= N <= 32767 )。之间用一个空格分开。
输出
输出M行,每行一个整数。
样例输入
8 5
样例输出
5
2
8
7
1
4
6
3
提示
分析:这样一道题用指针的方法解很直观。但用数组的方法也可以做出来。
我们设数组A有M个变量,每个变量中放的数是1。现在计数器K从1开始向后数,每数一个变量则累加器S把变量中的数相加。当数到最后一个变量M时,自动转向第一个变量接着数。当累加器的数到N时,最后一个被加的变量出列(打印其下标值,同时将该变量的值由1变为0),同时累加器的值清零。然后从出列的下一个变量又开始向后累加每个变量的值,直到加到N时,最后一个被加的变量出列......用这种方法不担心出列的变量被重复相加,因为一旦被判出列,该变量的值由1变为0,
即使相加也无妨。 展开
有M个人,其编号分别为1-M。这M个人按顺序排成一个圈。现在给定一个数N,从第一个人开始依次报数,数到N的人出列,然后又从下一个人开始又从1开始依次报数,数到N的人又出列...如此循环,直到最后一个人出列为止。
输入
输入只有一行,包括2个整数M(8 <= M <= 15 ),N( 5 <= N <= 32767 )。之间用一个空格分开。
输出
输出M行,每行一个整数。
样例输入
8 5
样例输出
5
2
8
7
1
4
6
3
提示
分析:这样一道题用指针的方法解很直观。但用数组的方法也可以做出来。
我们设数组A有M个变量,每个变量中放的数是1。现在计数器K从1开始向后数,每数一个变量则累加器S把变量中的数相加。当数到最后一个变量M时,自动转向第一个变量接着数。当累加器的数到N时,最后一个被加的变量出列(打印其下标值,同时将该变量的值由1变为0),同时累加器的值清零。然后从出列的下一个变量又开始向后累加每个变量的值,直到加到N时,最后一个被加的变量出列......用这种方法不担心出列的变量被重复相加,因为一旦被判出列,该变量的值由1变为0,
即使相加也无妨。 展开
3个回答
展开全部
我原来写的,不知道合不合你的情况,希望能给你帮助,另外编程还是要靠自己
望采纳
//约瑟夫问题
#include "stdio.h"
#include "stdlib.h"
#include "vector"
using namespace std;
void main()
{
vector<int> a;/*当前人是否被排除,0为未排除,1为被排除*/
int s=0/*总人数*/,i=0/*循环控制变量*/,j=0/*本轮的序数*/,k=0/*已排除的人数*/,n=0/*排除间隔*/;
printf("输入总人数:");
scanf("%d",&s);
printf("输入输出间隔:");
scanf("%d",&n);
for(i=0;i<s;i++)
a.push_back(0);
j=1;/*初始化*/
for(i=0;i<=s-1;i++)
{
if(a[i]==0)/*如果a[i]未被排除则执行*/
{
if(j==n)/*当符合间隔时执行*/
{
printf("%4d\n",i+1);
a[i]=1;/*标记为已排除*/
j=0;/*重新为本轮计数*/
k++;/*总个数+1*/
}
j++;/*本轮+1*/
}
if(i==s-1)/*重新遍历每个人*/
i=-1;
if(k==s)/*全部输出完成时结束*/
break;
}
system("pause");
}
望采纳
//约瑟夫问题
#include "stdio.h"
#include "stdlib.h"
#include "vector"
using namespace std;
void main()
{
vector<int> a;/*当前人是否被排除,0为未排除,1为被排除*/
int s=0/*总人数*/,i=0/*循环控制变量*/,j=0/*本轮的序数*/,k=0/*已排除的人数*/,n=0/*排除间隔*/;
printf("输入总人数:");
scanf("%d",&s);
printf("输入输出间隔:");
scanf("%d",&n);
for(i=0;i<s;i++)
a.push_back(0);
j=1;/*初始化*/
for(i=0;i<=s-1;i++)
{
if(a[i]==0)/*如果a[i]未被排除则执行*/
{
if(j==n)/*当符合间隔时执行*/
{
printf("%4d\n",i+1);
a[i]=1;/*标记为已排除*/
j=0;/*重新为本轮计数*/
k++;/*总个数+1*/
}
j++;/*本轮+1*/
}
if(i==s-1)/*重新遍历每个人*/
i=-1;
if(k==s)/*全部输出完成时结束*/
break;
}
system("pause");
}
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
【不多说了,有图有真相】
8 5
5
2
8
7
1
4
6
3
测试数据2
20 6
6
12
18
4
11
19
7
15
3
14
5
17
10
8
2
9
16
13
1
20
【正确的代码】
#include "stdio.h"
#include "conio.h"
main()
{
int student[50];
int n=0,count=0,number=0,i,j;
scanf("%d %d",&number,&n);
for(i=1;i<=50;i++)
{
student[i-1]=i;
}
i=0;
while(number>1)
{
count=1;
while(count<=n-1)
{
i++;
count++;
if(i>=number)
{
i=i%number;
}
}
printf("%d\n",student[i]);
for( j=i+1;j<number;j++)
{
student[j-1]=student[j];
}
number--;
}
printf("%d",student[0]);
getch();
}
8 5
5
2
8
7
1
4
6
3
测试数据2
20 6
6
12
18
4
11
19
7
15
3
14
5
17
10
8
2
9
16
13
1
20
【正确的代码】
#include "stdio.h"
#include "conio.h"
main()
{
int student[50];
int n=0,count=0,number=0,i,j;
scanf("%d %d",&number,&n);
for(i=1;i<=50;i++)
{
student[i-1]=i;
}
i=0;
while(number>1)
{
count=1;
while(count<=n-1)
{
i++;
count++;
if(i>=number)
{
i=i%number;
}
}
printf("%d\n",student[i]);
for( j=i+1;j<number;j++)
{
student[j-1]=student[j];
}
number--;
}
printf("%d",student[0]);
getch();
}
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
#include<stdio.h>
int main()
{
int n,s,m,t,i,num[105],j;
//scanf("%d",&t);
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=0;i<105;i++)
{
num[i]=i;
}
s=1;
for(i=s;n>=1;)
{
i=i+m-1;
if(i>n)
i=i%n;
if(i==0)
{
printf("%d\n",num[n]);
i=n;
}
else
printf("%d\n",num[i]);
for(j=i;j<n;j++)
{
num[j]=num[j+1];
}
n-- ;
}
//printf("\n%d win.\n",num[1]);
}
return 0;
}
int main()
{
int n,s,m,t,i,num[105],j;
//scanf("%d",&t);
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=0;i<105;i++)
{
num[i]=i;
}
s=1;
for(i=s;n>=1;)
{
i=i+m-1;
if(i>n)
i=i%n;
if(i==0)
{
printf("%d\n",num[n]);
i=n;
}
else
printf("%d\n",num[i]);
for(j=i;j<n;j++)
{
num[j]=num[j+1];
}
n-- ;
}
//printf("\n%d win.\n",num[1]);
}
return 0;
}
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询