算法:约瑟夫问题:01 来源:百度百科
Posted coding365
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法:约瑟夫问题:01 来源:百度百科相关的知识,希望对你有一定的参考价值。
https://baike.baidu.com/item/约瑟夫问题/3857719?fr=aladdin
Posted coding365
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法:约瑟夫问题:01 来源:百度百科相关的知识,希望对你有一定的参考价值。
https://baike.baidu.com/item/约瑟夫问题/3857719?fr=aladdin
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | var a: array [ 1..20 ] of integer ; n,m,i,j,k,n1,m1: integer ; begin readln(m,n); for i:= 1 to m do a[i]:=i; m1:=m; n1:= 1 ; while m1> 0 do begin j:=(n+n1- 1 - 1 ) mod m1 + 1 ; n1:=j; m1:=m1- 1 ; writeln (a[j]); for k:=j to m1 do a[k]:=a[k+ 1 ]; end ; end . |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #include<iostream> using namespace std; main() { bool a[101]={0}; int n,m,i,f=0,t=0,s=0; cin>>n>>m; do { ++t; //逐个枚举圈中的所有位置 if (t>n) t=1; //数组模拟环状,最后一个与第一个相连 if (!a[t]) s++; //第t个位置上有人则报数 if (s==m) //当前报的数是m { s=0; //计数器清零 cout<<t<< ‘ ‘ ; //输出被杀人编号 a[t]=1; //此处人已死,设置为空 f++; //死亡人数+1 } } while (f!=n); //直到所有人都被杀死为止 } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | #include <iostream> #include <iomanip> #include <cmath> using namespace std; int main() { int a[8],i,t,k; for (i=1;i<=8;i++) { a[i]=1; } t=8; k=0; while (t>0) { for (i=1;i<=8;i++) { if (a[i]==1) { k++; if (k==5) { k=0; a[i]=0; cout<<setw(3)<<i; t--; if (t==0) { break ; } } } } } return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | var n,m,i,s,p: integer ; a: array [ 1..10000 ] of integer ; begin read(n,m); //这步不用说了吧? for i:= 1 to n do a[i]:= 1 ; //先全部赋值1 p:= 0 ;s:= 0 ; //统计人数和报数字用的 repeat for i:= 1 to n do begin if a[i]= 0 then continue; //用于等会排除出圈者 s:=s+a[i]; //不断累加(报数字) if s=m then //出圈者 begin write (i, ‘ ‘ );打印出圈者; a[i]:= 0 ; //明白刚才continue的意思了吧 p:=p+ 1 ; //人数减少一个; s:= 0 ; //重头报起. end ; end ; until p=n; //直到人数到了 end . |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | Var a: array [ 1..100 ] of integer ; n,m,i,j,p: integer ; Begin write ( ‘Input n,m:‘ ); readln(n,m); for i:= 1 to n do a[i]:=i; p:= 1 ; {p用于记录报数的位置} for i:= 1 to n do begin j:= 0 ; {j用于记录报到的人数} while j<m do begin if a[p]<> 0 then j:=j+ 1 ; if p=n then p:= 1 else p:=p+ 1 ; {处理边界情况} end ; if p<> 1 then begin write (a[p- 1 ], ‘ ‘ );a[p- 1 ]:= 0 ; end {处理边界情况} else begin write (a[n], ‘ ‘ );a[n]:= 0 ; end ; end ; end . |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | Var a: array [ 1..100 ] of integer ; n,m,p,i,j: integer ; Begin readln(n,m); for i:= 1 to n- 1 do a[i]:=i+ 1 ; a[n]:= 1 ; p:=n; for i:= 1 to n do begin for j:= 1 to m- 1 do p:=a[p]; write (a[p], ‘ ‘ ); a[p]:=a[a[p]]; end ; End . |
1 2 3 4 5 6 7 8 9 10 | #include <iostream> using namespace std; const int m = 3; int main() { int n, f = 0; cin >> n; for ( int i = 1; i <= n; i++) f = (f + m) % i; cout << f + 1 << endl; } |
1 2 3 4 5 6 7 8 | var n,m,i,s: integer ; begin write ( ‘N M =‘ ); read(n,m); for i:= 2 to n do s:=(s+m) mod i; writeln ( ‘The winner is ‘ ,s+ 1 ); end . |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #控制参数: nums = 41 call = 3 #参数定义: peoples = [] for _ in range (nums): peoples.append( True ) result = [] num = 1 #主逻辑 while ( any (peoples)): for index,people in enumerate (peoples): if people: if num = = call: peoples[index] = False result.append(index + 1 ) # print(index+1)#每轮的出局者 # print(peoples)#每次的队列状态 num = 1 else : num + = 1 print ( ‘-‘ * 25 ) print ( ‘
总数为%d,报数为%d‘ % (nums,call)) print ( ‘约瑟夫序列为:
%s
‘ % result) print ( ‘-‘ * 25 ) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | var a,b,c: array [ 1..105 ] of longint ; la,lb,lc,i: longint ; s: string ; procedure incc; var i: integer ; begin for i:= 1 to 105 do c:=c+b; for i:= 1 to 104 do if c> 9 then begin c:=c+cdiv10; c:=c mod 10 ; end ; end ; functioncxiaoa: boolean ; vari: integer ; begin cxiaoa:= false ; fori:=105downto1do ifc<athenbegincxiaoa:= true ;break; end elseifc>athenbreak; end ; proceduredoubleb; vari: integer ; begin fori:=1to105dob:=b* 2 ; fori:=1to104doifb>9then begin b:=b+bdiv10; b:=bmod10; end ; end ; proceduredecc; vari,j: integer ; begin fori:=1to104do ifc>=bthenc:=c-belse begin j:=i+ 1 ; whilec[j]=0doinc(j); whilej>ido begin c[j]:=c[j]- 1 ; c[j- 1 ]:=c[j- 1 ]+ 10 ; dec(j); end ; c:=c-b; end ; end ; procedurefua; vari: integer ; begin fori:=1to104do ifa>cthena:=a-celse begin a:=a- 1 ; a:=a+ 10 ; a:=a-c; end ; end ; procedureoutit; vari,j: integer ; begin fori:=1to105doa:=a* 2 ; fori:=1to104doifa>9then begin a:=a+adiv10; a:=amod10; end ; ifa[ 1 ]>0thena[ 1 ]:=a[ 1 ]-1else begin j:= 2 ; whilea[j]=0doinc(j); whilej>1do begin a[j]:=a[j]- 1 ; a[j- 1 ]:=a[j- 1 ]+ 10 ; dec(j); end ; a[ 1 ]:=a[ 1 ]- 1 ; end ; fori:=105downto1doifa>0thenbeginj:=i;break; end ; fori:=jdownto1dowrite(a); end ; begin readln(s); la:=length(s); fori:=ladownto1doa:=ord(s[la+ 1 -i])-ord( ‘0‘ ); b[ 1 ]:= 1 ; c[ 1 ]:= 1 ; whilecxiaoado begin doubleb; incc; end ; decc; fua; outit; end . |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | #include <stdio.h> #include <malloc.h> #defineLENsizeof(structmonkey)//定义structmonkey这个类型的长度 struct monkey { int num; struct monkey *next; }; struct monkey *create( int m) { struct monkey *head,*p1,*p2; inti; p1=p2=( struct monkey*) malloc (LEN); head=p1; head->num=1; for (i=1,p1->num=1;i<m;i++) { p1=( struct monkey*) malloc (LEN); p1->num=i+1; p2->next=p1; p2=p1; } p2->next=head; return head; } struct monkey *findout( struct monkey *start, int n) { int i; struct monkey *p; i=n; p=start; for (i=1;i<n-1;i++) p=p->next; return p; } struct monkey *letout( struct monkey *last) { struct monkey *out,*next; out=last->next; last->next=out->next; next=out->next; free (out); return next; } int main() { int m,n,i,king; struct monkey *p1,*p2; printf ( "请输入猴子的个数m:
" ); scanf ( "%d" ,&m); printf ( "每次数猴子的个数n:
" ); scanf ( "%d" ,&n); if (n==1) { king=m; } else { p1=p2=create(m); for (i=1;i<m;i++) { p2=findout(p1,n); p1=p2; p2=letout(p1); p1=p2; } king=p2->num; free (p2); } printf ( "猴王的编号是:%d
" ,king); return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | //猴子选大王问题(约瑟夫环问题) #include<stdio.h> #include<string.h> #include<stdlib.h> intfre(charmok[],intk) { inti; printf ( "
猴子编号:
" ); for (i=0;mok[i]!= ‘ ‘ ;i++) printf ( "%d " ,mok[i]); //输出为踢出之前的编号,测试用 for (i=k;mok[i]!= ‘ ‘ ;i++) { mok[i]=mok[i+1]; } //一个循环,将k以后的元素前移 putchar ( ‘
‘ ); for (i=0;mok[i]!= ‘ ‘ ;i++) printf ( "%d " ,mok[i]); //输出踢出之后的编号,测试用 printf ( "
按回车继续下一轮:
" ); getch(); //暂停,测试用 return0; } int main() { char mok[50]; int i; int n,s,b; //n表示猴子总数;s表示步进;b表示元素个数及大王编号 int j,k; //j,k都是计数器 mok[0]=1; //初始化mok[0],让后面编号更简单的进行 printf ( "请输入猴子的总数:
" ); scanf ( "%d" ,&n); //输入猴子的总数 for (i=1;i<n;i++) { mok[i]=i+1; } //对猴子进行编号 mok[n]= ‘ ‘ ; //用0来表示数组的结尾 printf ( "请输入循环单位:
" ); scanf ( "%d" ,&s); //单位长度 b=n; //统计猴子的个数 for (j=1,k=0;;j++,k++) { if (b==1) { b=mok[0]; break ; } //如果元素只剩下一个,那么退出循环 if (j==s) { printf ( "
它出列了:%d
" ,mok[k]); fre(mok,k); //用于元素前移的函数 b--; j=1; } //将猴子从数组中踢出,并重置计数器J。 if (mok[k+1]== ‘ ‘ ) k=-1; //重置计数器k,因为后面有k++所以k要在重置基础上-1. } //判断是否为数组最后元素,重置计数器k。 printf ( "
最终大王是他:%d
" ,b); return0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #include<stdio.h> #include<malloc.h> int main() { int *person,i,node,n,m; scanf ( "%d%d" ,&n,&m); person=( int *) malloc ( sizeof ( int )*(n+1)); for (i=1;i<n;i++) //初始化圈 { person[i]=i+1; //i表示编号为i的人,person[i]的值表示编号为i的人的下一个人的编号 } person[n]=1; //编号为n的下一个人的编号是1 node=1; while (node!=person[node]) //如果某个人的下一个人不是自己,意味着人数超过1人 { for (i=1;i<m-1;i++) //这个循环终止于被杀的人的前一个人 { node=person[node]; //下一个人的编号为node,node的值来自于前一个人的person[node] } printf ( "%d" ,person[node]); //输出被杀的人编号 person[node]=person[person[node]]; //修改被杀的人的前一个人的person[node]为被杀的人的后一个人的编号 node=person[node]; //这句话中的node是被杀的人后一个人 } printf ( "%d" ,node); //输出最后幸存者的编号 return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | var a:array[ 1. . 10000 ]ofinteger; n,s,i,j:integer; begin read(m,n); fori: = 1tomdoa [i]: = 1 ; j: = 0 ; fori: = 1tomdo begin s: = 0 ; whiles<ndo begin ifj<mtheninc(j) elsej: = 1 ; s: = s + a[j]; end; write(j); a[j]: = 0 ; end; end. |
1 2 3 4 5 6 7 8 9 10 11 12 13 | #include<iostream> #include<conio.h> using namespace std; main() { int n,m,i,s=0; cout<< "N:" ;cin>>n; cout<< "M:" ;cin>>m; for (i=2;i<=n;i++) s=(s+m)%i; cout<< "新的大王是:" <<s+1; getch(); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include<stdio.h> #include<conio.h> intmain( void ) { intn,i=0,m,p; scanf ( "%d%d" ,&n,&m); //n总人数,m步长 while (++i<=n) { p=i*m; while (p>n) p=p-n+(p-n-1)/(m-1); printf ( "%d
" ,p); } getch(); return0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #include<iostream> usingnamespacestd; intking(intM,intN) { intk=0; for (inti=2;i<=M;i++) k=(k+N)%i; return ++k;}i ntmain() { intn,m; while ( scanf ( "%d%d" ,&n,&m)&&n&&m) { cout<<king(n,m)<<endl; } return0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 | function king( $n , $m ){ $monkey = range(1, $n ); //模拟建立一个连续数组 $i =0; while ( count ( $monkey )>1){ $i +=1; //开始查数 $head = array_shift ( $monkey ); //直接一个一个出列最前面的猴子 if ( $i % $m !=0 ){ array_push ( $monkey , $head ); //如果没数到m或m的倍数,则把该猴放回尾部去. } //否则就抛弃掉了 } return $monkey [0]; } echo ‘剩余‘ ,king(3,4), ‘号猴子‘ ; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | def Monkey(n, M): if n = = 0 or M = = 1 : #过滤两种特殊情况 return 0 L = list ( map ( list , list ( enumerate ([ True ] * n,start = 1 )))) #两种状态以布尔值表示 counter = 0 while [L[i][ 1 ] for i in range ( len (L))].count( True ) > 1 : for i in range ( len (L)): if L[i][ 1 ] = = True : counter + = 1 if counter % M = = 0 and L[i][ 1 ] = = True : L[i][ 1 ] = False return list ( filter ( lambda x:x[ 1 ] = = True , L))[ 0 ][ 0 ] Monkey( 2009 , 3 ) |
以上是关于算法:约瑟夫问题:01 来源:百度百科的主要内容,如果未能解决你的问题,请参考以下文章