C语言 有n个人围成一圈,按顺序从1到n编号。从第一个人开始报数,报数3的人退出圈子

有n个人围成一圈,按顺序从1到n编号。从第一个人开始报数,报数3的人退出圈子,下一个人从1开始重新报数,报数3的人退出圈子。如此循环,直到留下最后一个人。问留下来的人的编号。

【输入形式】

考虑如下两种情况:

如果n超出“n must be a natural number less than 10000”,则打印“n is out of range of valid values.”;其中n应该用如上输入的具体的n数值代替;换行;

如果n是有效范围的数值,则打印“Last No. is:”;然后直接在冒号后面输出最后留下来的人的编号;换行;

【运行时的输入输出样例1】(下划线部分表示输入)

Input n(n must be a natural number less than 10000):5

Last No. is:4

【运行时的输入输出样例2】(下划线部分表示输入)

Input n(n must be a natural number less than 10000):100000

100000 is out of range of valid values.

我的程序为什么死循环啊....刚学指针,求改正,
#include <stdio.h>
#define N 9999
int main()
{
int n,a[N],*p,i=0,out=0,count=0;
printf("Input n(n must be a natural number less than 10000):");
scanf("%d",&n);
if(n>=10000)
printf("n is out of range of valid values.");
else
{
for(i=0;i<=n;i++)
a[i+1]=i;
p=a;
while(out!=n){
if(*p!=0)
count++;
if(count==3){
out++;
*p=0;
}
count=0;
p++;
if(*p==a[n-1])
p=a;
}
printf("%d",*p);
}
return 0;
}
修改后——————》
else
{
for(i=0;i<=n;i++)
a[i]=i;
p=a;
while(out!=n-1){
for(;;){
if(*p!=0){
count++;
p++;
}
if(count==3){
out++;
*p=0;
count=0;
break;
}
if(*p==a[n-1])
p=a;
}
}
printf("%d",*p);
}

#include <stdio.h>
#define N 9999
int main()
{
int n,a[N],*p,i=0,out=0,count=0;
printf("Input n(n must be a natural number less than 10000):");
scanf("%d",&n);
if(n>=10000)
printf("n is out of range of valid values.");改为printf("%d is out of range of valid values.",n);
else
{
for(i=0;i<=n;i++) 改为a[i]=i;
a[i+1]=i; //这样做a[0]是个不确定的值,执行完p=a;后*p
p=a; 的值也是不确定的,后面的if判断条件不确定了
while(out!=n){ 这儿应该是out!=n-1吧
if(*p!=0) 这段可以改成这样for(;;){ if(*p!=0){
count++; count++;p++;}结束if
if(count==3){ if(count==3){ out++; out++;
*p=0; *p=0; break;}结束if
} }结束for
count=0; //此处导致count永远只能是0或1所以out的值不会变
把这儿的p++删了 p++; while就成死循环了
if(*p==a[n-1]) 把这个if语句嵌套到if(*p!=0)里的p++后面这儿不要了
p=a;
}
printf("%d",*p);
}
return 0;
}
这样改完后应该能把最后剩下的号码打出,其实可以把出局的顺序也打出来楼主想想啊,挺简单的,而且好像有很短的代码解决这个问题,多思考啊追问

我重新根据你的改了下,还是死循环,逐步调试后,if(*p!=0)这个,全部被跳过了...
可是明明p是指向a[]的啊...然后就死循环了..
还有那个for(;;)是什么意思,没有判断等语句,不是等于没有用么?.

追答

确实不行,因为*p==0的情况没有处理,这样遇到一个*p==0就一直死循环了
至于那个for循环的判断语句在循环里面,就是那个break;也可以用while(1)来代替
把p=a;改为p=&a[1];后面循环写成下面这样看看

while(out!=n-1)
{
while(1)

if(*p!=0)
count++;
if(p==&a[n])
p=&a[1];
else
p++;
if(count==3)
{
if(p==&a[1])
a[n]=0;
else
p--;
out++; //在这儿家加上printf("%d->",*p);就可以把顺序打出来了
*p=0;
break;

}结束while(1)
count=0;
}结束while(out!=n-1)
for(i=1;i<=n;i++)
if(a[i]!=0)
printf("%d",a[i])

这样应该就没问题了把,我自己没测试过你可以试试,还有问题的话在找我,不对管换而且没期限限制,呵呵呵大家多交流啊
这个我试过了OK

温馨提示:答案为网友推荐,仅供参考
第1个回答  2012-05-12
话说。。。不知道你这个是怎么弄的。。可以给你一段代码
#include <stdio.h>
#include <stdlib.h>
int cur=1;
int n=2;
typedef struct Monkey
{
int num;
struct Monkey *bef;
struct Monkey *next;
}monkey;
void creat(monkey *head)
{
monkey *p3,*p2;
p3=head;
p3->num=1;
printf("从多少中选大王? : ");
scanf("%d",&n);
int i;
for(i=2;i<=n;i++)
{
p2=(monkey *)malloc(sizeof(monkey));
p2->num=i;
p3->next=p2;
p2->bef=p3;
p3=p3->next;
}
p3->next=head;
head->bef=p3;
}
void print(monkey *head)
{
monkey *p4;
p4=head;
int i;
for(i=1;i<=n;i++)
{
printf("%d ",p4->num);
p4=p4->next;
}
printf("\n\n");
}
void fond(monkey *head,monkey *p1)
{
if(head->num==head->next->num)
{
printf("\n\n大王是 %d \n",head->num);
}
else
{
cur++;
p1=p1->next;
if(cur==3)
{
cur=1;
p1->bef->next=p1->next;
p1->next->bef=p1->bef;
if(p1==head)
{
p1=p1->next;
head=p1;
}
else
p1=p1->next;
}
fond(head,p1);
}
}
void main()
{
monkey *head,*p1;
head=(monkey *)malloc(sizeof(monkey));
p1=head;
creat(head);
print(head);
fond(head,p1);
}
但是我的这个没有那个超过10000的处理,你自己加加吧!
第2个回答  2012-05-13
cout和cin是C++新增的,与C语言的printf和scanf一致,我写的这个算法没有人数上限,我怎么总觉得我写的比楼上好呢= =你可以试着运行一下,虽然结果一样,但是我算法的运行速度快多了
#include<iostream>
using namespace std;
#define NEW (struct num*)malloc(sizeof(struct num))
main()
{
cout<<"游戏规则:\n有n个人围成一圈,按顺序从1到n编号(n大于等于2)。从第一个人开始报数,报数3的人退出圈子,下一个人从1开始重新报数,报数3的人退出圈子。如此循环,直到留下最后一个人。问留下来的人的编号。\n\n";
cout<<"输入n=";
int n;
cin>>n;
if(n==1)
{
cout<<"n必须大于等于2\n";
exit(0);
}
struct num
{
int a;//a为编号
struct num*next;
};
num*h,*p,*q;
p=NEW;
if(p==0)
{
cout<<"内存溢出\n";
exit(0);
}
p->a=1;
p->next=0;
h=q=p;
for(int i=2;i<=n;i++)
{
p=NEW;
if(p==0)
{
cout<<"内存溢出\n";
exit(0);
}
p->a=i;
p->next=0;
q->next=p;
q=p;
}
p->next=h;
p=h;
int j=1;//j为报数
for(i=1;i<n;)//i为出列人数
{
if(j>=2)
{
q=p->next->next;
p->next=q;
p=q;
j=0;
i++;
}
else
p=p->next;
j++;
}
cout<<"最后留下的人为"<<p->a<<"号\n";
}追问

这个貌似不是C语言吧...看不懂饿...或者是我还没交到..p->a=i;之类的...

追答

是C语言,你自己运行以下就知道了,只有cin和cout语句是C++扩充的,这个我在上面就说过了,主体思路是用动态单向链表做的,就是你说的那个p->a=i;之类的,别慌,后面会教,等你指针弄熟了很简单的

相似回答