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

作者&投稿:淳会 (若有异议请与网页底部的电邮联系)
C语言:有n个人围成一圈,按顺序从1到n编号。从第一个人开始报数,报数3的人退出圈子~

#include const int M = 3;int main(){ int n, s = 0; scanf("%d", &n); if(n>10000) { printf("n must be a natural number less than 10000
"; printf("%d is out of range of valid values.",n); printf("Please Enter again :
"); scanf("%d", &n); } for (int i=2;i<=n;++i) s=(s+M)%i; printf("Last No. is %d
",s+1); return 0;}

#include
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;
}

扩展资料:
需要说明的是:
1、一个C语言源程序可以由一个或多个源文件组成。
2、每个源文件可由一个或多个函数组成。
3、一个源程序不论由多少个文件组成,都有一个且只能有一个main函数,即主函数。是整个程序的入口。
4、源程序中可以有预处理命令(包括include 命令,ifdef、ifndef命令、define命令),预处理命令通常应放在源文件或源程序的最前面。
5、每一个说明,每一个语句都必须以分号结尾。但预处理命令,函数头和花括号“}”之后不能加分号。结构体、联合体、枚举型的声明的“}”后要加“ ;”。
6、标识符,关键字之间必须至少加一个空格以示间隔。若已有明显的间隔符,也可不再加空格来间隔。
参考资料:
百度百科-c语言

此题可用数学方法求解。


设有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 <stdio.h>
const int M = 3;
int main()
{
    int n, s = 0;
    scanf("%d", &n);
    for (int i = 2; i <= n; ++i)
        s = (s+M)%i;
    printf("%d
", s+1);
    return 0;
}


1 #include <stdio.h>
2 #include <stdlib.h>
3 #define N 21 //人数
4 #define M 3 //报的倍数
5 int main()
6 {
7 int name[N];
8 int i,j=0,left=N,n=0;
9 for(i=0;i<N;i++)
10 name[i]=1;
11 while(left>1){
12 if(j>=N)
13 j=j%N;
14 if(name[j]==1){
15 n++;
16 if(n%M==0){
17 name[j] = 0;
18 left--;
19 }
20 }
21 j++;
22 }
23 for(i=0;i<N;i++){
24 if(name[i]==1)
25 printf("===%d\n",i+1);
26 }
27 }

亲,你能说清楚点嘛

你想问的是不是约瑟夫环?
可以看看这个网页
http://baike.baidu.com/view/717633.htm

递归实现


n个人围成一圈,有多少种排法
n个人围成一个圈,由于圆圈排列的特殊性(即圆周排列),首位相连,所以不能简单地看作是n个位置有n种排列方式。实际上,当n个人围成一圈时,固定一个人的位置之后,其余的人相对于这个人的位置就可以有 (n减1)感叹号种排列方法。总的排列数是 n感叹号分之n =等于(n减1)感叹号种不同的排列方式...

n个人围一个圈,外面的圆的周长是多少?
+n(每人所占外圆的长度)例如10个肩宽1.3尺的人间距1.2尺围成一圈,周长是:1.2×10+1.3×10+13=25尺 n个人排成一列(横排)的间距比围成一圈的间距少一个,每人所占的宽度是肩宽。,按上式的基础条件,列宽列式为:1.2(10-1)+1.3×10 1.2×9+13 10.8+13 =23.8尺 ...

有n个人围成一圈,按顺序从1到n编号。从第一个人开始报数,报数3的人退 ...
p = a,表示的是p指向的是数组的首地址。n+a表示的数组的尾地址。意思就是如果指针指向数组最后一个数,则跳回到第一个。。。就是题目提到的围成一个圈。

C语言 有n个人围成一圈,按顺序从1到n编号。从第一个人开始报数,报数3...
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;} 这样改完后应该能把最后剩下的号码打出,其实可以把出...

n个人围成一圈和排成一列的排列方法分别怎么计算?
比如:1234…..n和234…..n1就是两种不同的排列情况,但是如果将这两种排列首尾相接分别围成两个圈,就会发现这是两个一样的圈,元素的相对位置都是一样的,所以不能把环形排列看成单纯的排成一排。不妨这样思考,1作为这五个元素中的一员,,把位置固定不变,所有人围着他来站位,是可以组成全...

有n个人围成一圈,按顺序从1到n编号。从第一个人开始报数,报数3的人退 ...
while(t==1) \/\/如果还剩下一个人,跳出循环 { if(i==N) \/\/这里是头尾衔接成一个圈 i=0;if(a[i]!=0) \/\/这里是计数报数 j++;if(j==2) \/\/这里是出圈子的人 { a[i]=0;j=0;t--;} i++;} for(i=0;i<N;i++)if(a[i])printf("%d",i+1);...

约瑟夫问题
报数分为杀1留2,即1,2,1,2报数,报1的人死,报2的人留下。杀2留1,即1,2,1,2报数,报1的人留下,报2的人死。约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。例如N=6,M=5,被杀掉的人的序号为5,4,6...

有n个人围成一圈从1-3报数
n个人按顺序围成一圈(编号为1~n),从第1个人从1开始报数,报到k的人出列,相邻的下个人重新从1开始报数,报到k的人出列,重复这个过程,直到队伍中只有1个人为止,这就是约瑟夫问题。现在给定n和k,你需要返回最后剩下的那个人的编号。二、约瑟夫问题 约瑟夫问题,或称“约瑟夫环”,又名“丢手绢...

C语言指针问题 n人围成一圈,按顺序1-n编号,从第一个人开始报数,报到m...
for(p=a;n==1;p++){ cnt++;if(cnt==6) \/\/? 按你的意思,这个应该是 cnt==m吧?{ del(a,n,*p);n--;cnt=1;printf("号码为%d的人退出了圈子。\\n",*p-1);} if(p==&a[n]) p=a;} void del(int a[],int n,int x){ int i,j;for(i=0;i<n;i++){ if(a[i...

概率论问题求解:n个人随机围成一圈,指定的两个人相邻的概率是多少...
2\/(n-1)解法一:不管甲坐在什么位置,剩下n-1个位置里,乙有两个可选位置,所以是2\/(n-1)这应该是最简便的解法了 解法二:总共n个人围一圈,有 (n-1)! 个坐法 甲乙要坐在一起,那么就让他们坐一起,他们谁在左谁在右,有2种。其他n-2个人,(n-2)! 个坐法。所以是 2*(n-2)...

赣县13733672594: C语言:有n个人围成一圈,按顺序从1到n编号.从第一个人开始报数,报数3的人退出圈子 -
弓该益肾: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18#include <stdio.h> constintM = 3; intmain() {intn, s = 0;scanf("%d", &n);if(n>10000){printf("n must be a natural number less than 10000 \n";printf("%d is out of range of valid values.",n);...

赣县13733672594: 有n个人围成一圈,按顺序从1到n编号.从第一个人开始报数,报数3的人退出圈子,下一个人从1开始重新报数,用指针怎么写,核心的算法有点想不明白 -
弓该益肾:[答案] int a[N]={1}; int i=0,t=N,j=0; while(t==1) //如果还剩下一个人,跳出循环 { if(i==N) //这里是头尾衔接成一个圈 i=0; if(a[i]!=0) //这里是计数报数 j++; if(j==2) //这里是出圈子的人 { a[i]=0; j=0; t--; } i++; } for(i=0;i

赣县13733672594: 一高中数学问题N个人在操场里围成一圈,将这N个人按顺时针方向从1到N编号,然后从第一个人起每隔一个人让下一个人离开操场,显然第一轮过后具有偶... -
弓该益肾:[答案] 结果为1 J(400) 人数变化如下 400 200 100 50 25 13 7 4 2 1 而 J(1)=1 J(2)=1 J(4)=1 J(7)=1 . J(400)=1

赣县13733672594: 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++;} /*最后打印剩下一人的编号*/ } 请采纳

赣县13733672594: java编程,有n个人围成一圈,顺序排号,从一号到n号,从第一个开始报数,(从1报到3)凡报到3的 -
弓该益肾: 这么经典的面向对象题目 以下代码仅供参考 import java.util.Scanner;public class Main { public static void main(String[] args) {int n;Scanner scanner = new Scanner(System.in);System.out.println("请输入一个正整数:");n = scanner....

赣县13733672594: 编程:n个人围一圈,按1至n编号. -
弓该益肾: 约瑟夫公式: 令f(1)=0,那么f(n)=(f(n-1)+m)%n.由于最终计算出的f(n)是从0开始的,f(n)再加1即为最后一人员对应的数字. 以java代码为例,代码如下: public class Test { public static void main(String[] args) { int n = 5, m = 3; if (n < 1 || m < 1) ...

赣县13733672594: C语言:用指针:n个人围成一圈,依次从1到n编号.从编号为1的人开始报数,凡报数为3的人退出圈子, -
弓该益肾: #include int last(int n){ int i,a[1000]; int total=0,sum=0; for(i=0;ia[i]=1; i=0; while(1){ sum+=a[i]; if (sum==3){ a[i]=0; total++; sum=0; if (total==n) return i+1; } i++; i=i%n; } } int main(){ int n,i; int *p; scanf("%d",&n); p=(int *)malloc(sizeof(int)*n); for(i=0;...

赣县13733672594: 假定有N个小朋友,分别编号为1到N,他们按编号围成一个圆圈,从1开始报数,当报到3的小朋友出列,由下一个小朋友重新开始报1,直到最后剩下一个小... -
弓该益肾:[答案] static void LastLeaver(int nums, int count) { int[] num = new int[nums]; for (int index = 0; index解析看不懂?免费查看同类题视频解析查看解答

赣县13733672594: 关于错排序问题有一列人,按1到n的顺序对这n个人进行编号.现在这n个人开始排队,有一个排序规则就是编号为i的人不能站在第i位上,问:n个人进行排... -
弓该益肾:[答案] 所有排列有n!种,考虑第k位上是k的排列共有(n-1)!种,k可以取1,2,...,n,所以共有n*(n-1)!种,以上这些种都是不满足条件的情况应该被减去,但是有些情况被多减了,就是第k位和第m为上同时是k,m这种情况被减了2次,所以应该给这部分加...

赣县13733672594: 有n个人围成一圈,按顺序从1到n编好号.从第一个开始报数,报到3的人退出圈子,下一个人从1开始报数, -
弓该益肾: #include <stdio.h> #define N 10 //定义个数 #define C 3 //定义报数int main() {int a[N];int i,j,count; //初始化数组for(i=0;i<N;i++){a[i]=i+1;}count=N;//计数器 //循环处理前N-1个编号,每次查找出,将计数器递减,直到为1printf("依次...

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网