怎么得不到正确答案

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

void main()
{
int i,k,m,n,num[50],*p;
printf("input number of person:n=");
scanf("%d",&n);
p=num;
for(i=0;i<n;i++)
*(p+i)=i+1;
i=0;
k=0;
m=0;
while(m<n-1)
{
if(*(p+i)!=0)k++;
if(k==3)
{*(p+i)=0;
k=0;
m++;
}
i++;
if(i==0)i=0;
}
while(*p==0)p++;
printf("the lase one is NO.%d\n",*p);
}

运行结果:
input number of person: n=8
the last one is NO.1
正确应该是 7 号 ,错在那里,同时请帮解释一下程序

12 个解决方案

#1


这个题好像书上有,
和书上的比一下就知道了

#2


就是约瑟夫环嘛!搜索一下很多的

#3


//if(i==0)
//i=0;

if(i==n)
  i=0;

#4


if(i==0)修改为:if(i>=n)i=0;

OK!
你没有环状的操作。

#5


up up

#6


zteliubin(bill) ( ) 
right ,无环操作~~~~~
vc++6.0调试通过
输入8
结果为7

#7


请大家帮详细的解释程序运行的过程。迷惑----

#8


#include <iostream>
using namespace std;

struct list
{
// 保存位置信息
int position;

// 指向 数组中下一个元素
struct list* next;
};

typedef struct list LIST;

int main(void)
{
// 定义 50 个
LIST mylist[50];

printf("请输入一个1-50的数\n");

int x;
scanf("%d", &x);

// 给链表初始值
for (int i = 0; i < x - 1; i++)
{
mylist[i].position = i + 1;
mylist[i].next = &mylist[i + 1];
}
mylist[x - 1].position = x;
mylist[x - 1].next = &mylist[0];

// x 个人 做 x - 1 次,就剩下一个了 
// So

// 做 x -1 次 逢3个 空一个
// 然后, 下次 从空掉的那个后一个 做起
i = 0;
int j = 0;
do
{
mylist[i].next->next = mylist[i].next->next->next;
i = mylist[i].next->next->position - 1;
j++;

}
while (j < x - 1);

// 打印位置
printf("\n\n%d\n", mylist[i].position);
}

#9


程序注释:

void main()
{
int i,k,m,n,num[50],*p;
printf("input number of person:n=");
scanf("%d",&n);

//初始化,令p[i]等于i+1,就等于给每个人编了个号。
//报数过程中,被剔除的人其号码会被置成0,于是
//等报完数,剩下那个人的编号就是我们要得到的结果。
p=num;
for(i=0;i<n;i++)
*(p+i)=i+1;

i=0;
//标记数组下标的变量,在报数过程中,循环使用,答到n便会重新从0开始,
//从而实现“围成圈”的模拟。

k=0;
//报数的变量,在0,1,2之间循环(达到3,便被重新置成0,同时删除当年的那个“人”)

m=0;
//记录已经又多少个人被剔除的变量,当m等于n-1,就只剩下我们要得到的那个人了。
//注意此时i中记录的就是这个下标,而p[i]就是我们要得到的编号(实际上也就是此时的i加1)。

while(m<n-1)
{
//在没有下去的人当中报数,*(p+1)即p[i],若某个p[i]为0,说明他已经下去了。
if(*(p+i)!=0)
k++;

//报到3的人出局,即p[i]被置成0。
if(k==3)
{
*(p+i)=0;
k=0;
m++;
}

//下一次该检查下一个人了。
i++;

//n-1晚了应该是0,而不是n。所以当i等于n是,置成0。
if(i==n)
i=0;
}

//查找那个没有被置成0的家伙。
while(*p==0)
p++;

//打印出他的编号。
printf("the lase one is NO.%d\n",*p);
}

#10


简单的约瑟夫问题,数据结构的入门级题目...

#11


太经典的题目

清华那本有好多解法

#12


to njuhuangmy(茶) 
你的程序好像有几个问题.
我用dev-C++编译时,提示我没有iotream这个函数库,当然,在for里面把i定义了一下后,还需要在外边定义,可能时编译器不同吧.
后来我又在vc++6.0下编译,还时没通过,提示错误时这样的,
G:\c program\约瑟夫环1.cpp(3) : error C2871: 'std' : does not exist or is not a namespace
G:\c program\约瑟夫环1.cpp(28) : error C2086: 'i' : redefinition
不知道时什么回事.你的程序在你的系统上是不是通过了?如果是的话能不能告诉我哪里不一样?
我用的是2000系统.

#1


这个题好像书上有,
和书上的比一下就知道了

#2


就是约瑟夫环嘛!搜索一下很多的

#3


//if(i==0)
//i=0;

if(i==n)
  i=0;

#4


if(i==0)修改为:if(i>=n)i=0;

OK!
你没有环状的操作。

#5


up up

#6


zteliubin(bill) ( ) 
right ,无环操作~~~~~
vc++6.0调试通过
输入8
结果为7

#7


请大家帮详细的解释程序运行的过程。迷惑----

#8


#include <iostream>
using namespace std;

struct list
{
// 保存位置信息
int position;

// 指向 数组中下一个元素
struct list* next;
};

typedef struct list LIST;

int main(void)
{
// 定义 50 个
LIST mylist[50];

printf("请输入一个1-50的数\n");

int x;
scanf("%d", &x);

// 给链表初始值
for (int i = 0; i < x - 1; i++)
{
mylist[i].position = i + 1;
mylist[i].next = &mylist[i + 1];
}
mylist[x - 1].position = x;
mylist[x - 1].next = &mylist[0];

// x 个人 做 x - 1 次,就剩下一个了 
// So

// 做 x -1 次 逢3个 空一个
// 然后, 下次 从空掉的那个后一个 做起
i = 0;
int j = 0;
do
{
mylist[i].next->next = mylist[i].next->next->next;
i = mylist[i].next->next->position - 1;
j++;

}
while (j < x - 1);

// 打印位置
printf("\n\n%d\n", mylist[i].position);
}

#9


程序注释:

void main()
{
int i,k,m,n,num[50],*p;
printf("input number of person:n=");
scanf("%d",&n);

//初始化,令p[i]等于i+1,就等于给每个人编了个号。
//报数过程中,被剔除的人其号码会被置成0,于是
//等报完数,剩下那个人的编号就是我们要得到的结果。
p=num;
for(i=0;i<n;i++)
*(p+i)=i+1;

i=0;
//标记数组下标的变量,在报数过程中,循环使用,答到n便会重新从0开始,
//从而实现“围成圈”的模拟。

k=0;
//报数的变量,在0,1,2之间循环(达到3,便被重新置成0,同时删除当年的那个“人”)

m=0;
//记录已经又多少个人被剔除的变量,当m等于n-1,就只剩下我们要得到的那个人了。
//注意此时i中记录的就是这个下标,而p[i]就是我们要得到的编号(实际上也就是此时的i加1)。

while(m<n-1)
{
//在没有下去的人当中报数,*(p+1)即p[i],若某个p[i]为0,说明他已经下去了。
if(*(p+i)!=0)
k++;

//报到3的人出局,即p[i]被置成0。
if(k==3)
{
*(p+i)=0;
k=0;
m++;
}

//下一次该检查下一个人了。
i++;

//n-1晚了应该是0,而不是n。所以当i等于n是,置成0。
if(i==n)
i=0;
}

//查找那个没有被置成0的家伙。
while(*p==0)
p++;

//打印出他的编号。
printf("the lase one is NO.%d\n",*p);
}

#10


简单的约瑟夫问题,数据结构的入门级题目...

#11


太经典的题目

清华那本有好多解法

#12


to njuhuangmy(茶) 
你的程序好像有几个问题.
我用dev-C++编译时,提示我没有iotream这个函数库,当然,在for里面把i定义了一下后,还需要在外边定义,可能时编译器不同吧.
后来我又在vc++6.0下编译,还时没通过,提示错误时这样的,
G:\c program\约瑟夫环1.cpp(3) : error C2871: 'std' : does not exist or is not a namespace
G:\c program\约瑟夫环1.cpp(28) : error C2086: 'i' : redefinition
不知道时什么回事.你的程序在你的系统上是不是通过了?如果是的话能不能告诉我哪里不一样?
我用的是2000系统.