简单的约瑟夫问题:使用数组,模拟一个圈,每次数到m就标记为已读,num=0
接着从下一个人开始,如果到了最后一个人,就重新回到第一个人,继续开始寻找,如果没有被标记过num(数到的数字)++,直到所有人都退出圈子结束
源代码
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 int main() 6 { 7 int n,m; 8 bool vis[1000]; 9 int num=0,ans=0; 10 memset(vis,0,sizeof(vis)); 11 scanf ("%d%d",&n,&m); 12 for (int i= 1;i <= n+1;i++) 13 { 14 if (i==n+1) 15 i=1; 16 if (vis[i]==0) 17 num++; 18 if(num==m) 19 { 20 ans++; 21 printf ("%d ",i); 22 vis[i]=1; 23 num=0; 24 } 25 if (ans==n) 26 break; 27 } 28 return 0; 29 }
已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
例如:n = 9, k = 1, m = 5
【解答】
出局人的顺序为5, 1, 7, 4, 3, 6, 9, 2, 8。
第一种变法,从第k个人开始数,即把循环的初始值设为k即可
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 int main() 6 { 7 int n,m,k; 8 bool vis[1000]; 9 int num=0,ans=0; 10 memset(vis,0,sizeof(vis)); 11 scanf ("%d%d%d",&n,&m,&k); 12 for (int i= k;i <= n+1;i++) 13 { 14 if (i==n+1) 15 i=1; 16 if (vis[i]==0) 17 num++; 18 if(num==m) 19 { 20 ans++; 21 printf ("%d ",i); 22 vis[i]=1; 23 num=0; 24 } 25 if (ans==n) 26 break; 27 } 28 return 0; 29 }
编号为1,2,....,N的N个人按顺时针方向围坐一圈,每人持有一个密码(正整数).一开始任选一个正整数作为报数上限值M,从第一个人开始按顺时针方向自1开始顺序报数,报到M时停止报数.报M的人出列,将他的密码作为新的M值,从他在顺时针方向上的下一个人开始 重新从1报数,如此下去,直至所有人全部出列为止.试设计一个程序求出出列顺序.
测试数据:
N=7;7个人 的密码依次为:3,1,7,2,4,8,4,首先M值为6(正确的出列顺序应为6,1,4,7,2,3,5)
变式2:仍从第一个人开始数,只是每一次m都要重新更新,我们就在每次数到当前m的同时,将m更新
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 int main() 6 { 7 int n,m; 8 int a[1000]; 9 bool vis[1000]; 10 int num=0,ans=0; 11 memset(vis,0,sizeof(vis)); 12 scanf ("%d%d",&n,&m); 13 for (int i = 1;i <= n;i++) 14 scanf ("%d",&a[i]); 15 for (int i= 1;i <= n+1;i++) 16 { 17 if (i==n+1) 18 i=1; 19 if (vis[i]==0) 20 num++; 21 if(num==m) 22 { 23 ans++; 24 printf ("%d ",i); 25 vis[i]=1; 26 num=0; 27 m=a[i]; 28 } 29 if (ans==n) 30 break; 31 } 32 return 0; 33 }
n个人排成一圈。从某个人开始,按顺时针方向依次编号。从编号为1的人开始顺时针“一二一”报数,报到2的人退出圈子。这样不断循环下去,圈子里的人将不断减少。由于人的个数是有限的,因此最终会剩下一个人。试问最后剩下的人最开始的编号。
输入格式 Input Format
一个正整数n,表示人的个数。输入数据保证数字n不超过100。
输出格式 Output Format
一个正整数。它表示经过“一二一”报数后最后剩下的人的编号。
样例输入 Sample Input :9
样例输出 Sample Output:3
围绕着山顶有10个洞,狐狸要吃兔子。
兔子说:“可以,但必须找到我,我就藏身于这十个洞中,你从10号洞出发,先到1号洞找,第二次隔1个 洞找,第三次隔2个洞找,以后如此类推,次数不限。”
但狐狸从早到晚进 进出出了1000次,仍没有找到兔子。问兔子究竟藏在哪个洞里?
约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。
例如N=6,M=5,被杀掉的人的序号为5,4,6,2,3。最后剩下1号。
假定在圈子里前K个为好人,后K个为坏人,你的任务是确定这样的最少M,使得所有的坏人在第一个好人之前被杀掉。