c语言n个人围成一圈
‘壹’ c语言 有n个人围成一圈,按顺序从1到n编号。从第一个人开始报数,报数3的人退出圈子
#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;
}
这样改完后应该能把最后剩下的号码打出,其实可以把出局的顺序也打出来楼主想想啊,挺简单的,而且好像有很短的代码解决这个问题,多思考啊
‘贰’ C语言:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报 数),凡报到3的人退出圈子....
目测没有问题。结果显示最后剩下的那个数字。
逻辑为:
1、给数据赋值
for(i=0;i<n;i++)/*数组a存放原始编号*/
a[i]=i+1;
2、将报到3的人退出圈子,因为最后只剩下一人,所以条件是quit_num<n-1=99
while(quit_num<n-1)/*直到只剩下1人时*/
{if(a[i]!=0)k++; /*报数,等于0的已经退出圈子*/
if(k==3) /*报数为3*/
{a[i]=0; /*退出圈子*/
quit_num++; /*统计人数*/
k=0; /*下次报数重新从一开始*/
}
i++; /*下次循环判断数组的下一个*/
if(i==n)i=0; /*循环到数组的最后一个,下次循环指定到第一个*/
}
3、输出最后个数字
for(i=0;i<n;i++)
if(a[i]!=0)printf("%d",a[i]);
‘叁’ C语言:有n个人围成一圈,按顺序从1到n编号。从第一个人开始报数。
#include<stdio.h>
int main()
{
int i,n,N,out,a[1000];
out=i=n=0;
printf("输入约瑟夫圈大小 100 ");
scanf("%d",&N);
for(i=0;i<N;i++)
{
a[i]=1;
}
i=0;
while(out!=N-1)
{
if(a[i]==1)n++;
if(n==3){a[i]=0;n=0;out++;}
i++;
if(i==N)i=0;
}
for(i=0;i<N;i++)
if(a[i]==1)printf("最后剩下的是第%d个人",i+1);break;
return 0;
}
(3)c语言n个人围成一圈扩展阅读:
需要说明的是:
1、一个C语言源程序可以由一个或多个源文件组成。
2、每个源文件可由一个或多个函数组成。
3、一个源程序不论由多少个文件组成,都有一个且只能有一个main函数,即主函数。是整个程序的入口。
4、源程序中可以有预处理命令(包括include 命令,ifdef、ifndef命令、define命令),预处理命令通常应放在源文件或源程序的最前面。
5、每一个说明,每一个语句都必须以分号结尾。但预处理命令,函数头和花括号“}”之后不能加分号。结构体、联合体、枚举型的声明的“}”后要加“ ;”。
6、标识符,关键字之间必须至少加一个空格以示间隔。若已有明显的间隔符,也可不再加空格来间隔。
网络-c语言
‘肆’ C语言:有n人围成一圈,顺序排号。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,
法一(模拟法):
#include<iostream>
usingstd::cin;
usingstd::cout;
intmain()
{
intn;
cout<<"请输入n=";
cin>>n;
if(n<2)
{
cout<<"n必须大于2! 请重新输入n=";
cin>>n;
}
bool*a=newbool[n+1];
a[0]=false;
for(inti=1;i<n+1;i++)
a[i]=true;
intx,k=n;x=i=0;//i为每次循环计数变量,x为人员序号,K为剩余人数
while(k!=0)
{
x++;
if(x>n)x=1;//当人员到达数组尾,序号重设为1
if(a[x])i++;//跳过已退出人员
if(i==3)
{a[x]=false;i=0;k--;}//当数到3时,退出人员设为false,剩余人数减1,i设为0,重新计数
}
cout<<"留下来的人序号为:"<<x<<" ";
delete[]a;
cin.get();
cin.get();//等待下一次键击关闭窗口
return0;
}
法二(递归法):
此题可用数学方法求解。
设有n个人(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人继续从0开始报数 (用数学方法解的时候需要注意应当从0开始编号,因为取余会取到0解。)
实质是一个递推,n个人中最终留下来的序号与n-1个人中留下来的人的序号有一个递推关系式。
假设除去第k个人,则
0, 1, 2, 3, ..., k-2, k-1, k, ..., n-1 // 原始序列(1)
0, 1, 2, 3, ..., k-2, , k, ..., n-1 // 除去第k人,即除去序号为k-1的人 (2)
k, k+1, ..., n-1, 0, 1, ..., k-2// 以序号k为起始,从k开始报0 (3)
0, 1, ..., n-k-1, n-k, n-k+1, ..., n-2 // 作编号转换,此时队列为n-1人 (4)
变换后就完完全全成为了(n-1)个人报数的子问题,注意(1)式和(4)式,是同一个问题,不同的仅仅是人数。比较(4)和(3),不难看出,0+k=k, 1+k=k+1, ... ,(3)式中'0'后面的数字,
((n-3)+k)%n=k-3,((n-2)+k)%n=k-2, 对于(3)式中'0'前面的数字,由于比n小,也可看作(0+k)%n=k, (1+k)%n=k+1, 故可得出规律:
设(3)中某一数为x' , (4)中对应的数为x,则有:x'=(x+k)%n.
设x为最终留下的人序号时,队列只剩下1人时,显然x=0; 此时可向前回溯至2人时x对应的序号,3人时x对应的序号……直至n人时x的序号,即为所求。
#include<iostream>
usingnamespacestd;
constintm=3;
intmain()
{
intn,f=0;
cin>>n;
for(inti=2;i<=n;i++)
f=(f+m)%i;
cout<<f+1<<endl;
}
‘伍’ C语言有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报 数)凡报到3的人退出圈子麻烦注释下代码
#include<stdio.h>
#define N 5//人数
void main()
{
int a[N]={0},i=0,out_n=0,call_n=0,*p;
p=a;
while(1){//循环报数
if(*p==0){//如果健在
if(out_n==(N-1))break;//如果仅剩一人
call_n++;//报数
call_n%=3;//最大为3,到了3就从0开始
if(call_n==0){*p=1;out_n++;}//为0(即3)出局
}
p++;if(p==a+N)p=a;//循环转向下一人
}
printf("最后剩余者的编号是:%d ",p+1-a);
}
(5)c语言n个人围成一圈扩展阅读:
printf()函数是格式化输出函数,一般用于向标准输出设备按规定格式输出信息。在编写程序时经常会用到此函数。
函数的原型为:int printf(const char*format,...);函数返回值为整型。若成功则返回输出的字符数,输出出错则返回负值。
printf()函数的调用格式为:
printf("<;格式化字符串>",<参量表>);
其中格式化字符串包括两部分内容:一部分是正常字符;这些字符将按原样输出;另一部分是格式化规定字符,以"%"开始,后跟一个或几个规定字符,用来确定输出内容格式。
参量表是需要输出的一系列参数,其个数必须与格式化字符串所说明的输出参数个数一样多,各参数之间用","分开,且顺序一一对应,否则将会出现意想不到的错误。
规定符
%d十进制有符号整数
%u十进制无符号整数
%f浮点数
%s字符串
%c单个字符
%p指针的值
%e指数形式的浮点数
%x,%X无符号以十六进制表示的整数
%o无符号以八进制表示的整数
%g把输出的值按照%e或者%f类型中输出长度较小的方式输出
%p输出地址符
%lu 32位无符号整数
%llu 64位无符号整数
‘陆’ C语言编程:有n个人围成一圈,按顺序从1到n编号。从第一个人开始,报到3的人退出圈子。
这个问题叫约瑟夫环,就是一群人围成一圈,从第一个人开始,报到3的出列,看最后留下谁。
这个可以用循环链表来实现,你也可以网络下,网络里有许多关于约瑟夫环的问题!
这个是我以前写的代码,你可以参考下,n取的10
#include
struct
serial
{
int
num;
struct
serial
*next;
};
void
main()
{
int
i;
struct
serial
peo[100],*p,*q;
for(i=0;i<10;i++)
peo[i].num=i+1;
for(i=0;i<9;i++)
peo[i].next=&peo[i+1];
peo[9].next=peo;
q=p=peo;
while(p!=p->next
)
{
for(i=0;i<2;i++)
{
q=p;
p=p->next;
}
q->next
=p->next
;
printf("被删除的元素:%-4d\n",p->num);
p=q->next
;
}
printf("\n最后报号出来的是原来的:%d\n",p->num);
getchar();
}
‘柒’ C语言编一个程序:有N个人排成一圈
#include<stdio.h>
#define M 10 /*M是总人数*/
#define N 3 /*循环为3*/
void main(void)
{
int a[M], b[M]; /*数组a存放圈中人的编号,数组b存放出圈人的编号*/
int i, j, k;
for(i = 0; i < M; i++) /*对圈中人按顺序编号1—M*/
a[i] = i + 1;
for(i = M, j = 0; i > 1; i--){
/*i表示圈中人个数,初始为M个,剩1个人时结束循环;j表示当前报数人的位置*/
for(k = 1; k <= N; k++) /*1至N报数*/
if(++j > i - 1) j = 0; /*最后一个人报数后第一个人接着报,形成一个圈*/
b[M - i] = j? a[j - 1]: a[ i - 1]; /*将报数为N的人的编号存入数组b*/
if(j)
for(k = --j; k < i; k++) /*压缩数组a,使报数为N的人出圈*/
a[k] = a[k + 1];
}
for(i = 0;i < M – 1; i++) /*按次序输出出圈人的编号*/
printf(“%6d”, b[i]);
printf(“%6d\n”, a[0]); /*输出圈中最后一个人的编号*/
}
(2)上面的算法效率不高,用标记的方法修改(1)中程序,使之效率提高
代码如下:
#include <stdio.h>
#define M 10
#define N 3
#define START 0
void main(void)
{
int a[M], i = 0, k, count = 0;
while(i++ < M)
a[i - 1] = i;
for(i = START; count <= M - 1; count++)
{
for(k = 1; k <= N; a[i++] && ++k) /*a[i]若为零则++k运算被忽略*/
if(i > M - 1)
i = 0;
printf("%d ", i ? a[i - 1] : a[M - 1]);
a[(i ? (i - 1) : (M - 1))] = 0;
}
}
有不懂可以给我留言。这是我们刚做的实验,刚好被你碰到了,哈哈
‘捌’ c语言:有n个人围成一圈,从第一个人开始报数1、2、3,每报到3的人退出圈子。编程使用【链表】找出
#include<iostream>
#include<malloc.h>
using namespace std;
struct node
{
int no; //代表编号结点的数据
int code;//代表密码结点的数据
node *next;//代表后一个结点的地址
};
int main()
{
int m,n,i,j;
node *p,*q,*first;
m=3;
cout<<"请输入人数 n:";
cin>>n;
for(i=1;i<=n;i++)
{
if(i==1)
{
first=p=(node*)malloc(sizeof(node));
if(p==0)
return 0;
}
else
{
q=(node*)malloc(sizeof(node));
if(q==0)
return 0;
p->next=q;
p=q;
}
cout<<"请输入第 "<<i<<" 个人的密码: ";
cin>>(p->code);
p->no=i;
}
p->next=first; //让表尾指向表头形成循环链表
p=first;
cout<<"出列顺序为: ";
for (j=1;j<=n;j++)
{
for(i=1;i<m;i++,p=p->next);
m=p->code;
cout<<p->no<<" ";
p->no=p->next->no;
p->code=p->next->code;
q=p->next;
p->next=p->next->next;
free(q);
}
cout<<endl;
return 0;
}
‘玖’ c语言,有n个人围成一圈,按顺序从1到n编好号。从第一个人开始报数,报到m(m<n)的人退出圈子
#include<stdio.h>
int main()
{int m,n,a[100],out=0,i,j=0;
scanf("%d%d",&n,&m); /*输入m,n*/
for(i=0;i<n;i++)
a[i]=i+1;
while(out<n)
{for(i=0;i<n;i++)
{if(a[i]!=0)
j++;
if(j==m)
{printf("%d\n",a[i]);out++;j=0;a[i]=0;} /*依次打印退出人的编号*/
if(i==n-1) break;
}
}
i=0;
if(a[i]!=0)
{printf("%d",a[i]);i++;} /*最后打印剩下一人的编号*/
}
请采纳