约瑟夫huan
n个人(0,1,2,3,4...n-1),围成一圈,从编号为k的人开始报数,报数报到m的人出队(报数是1,2,...m这样报的)。下次从出队的人之后开始重新报数,循环往复,当队伍中只剩最后一个人的时候,那个人就是大王。现在,给定n,k,m,
请你求出大王的编号。
输入描述:
输入一行包含三个整数n,k,m 1<=n<=100,1<=k<=n-1,1<=m<=100
输出描述:
输出一个整数
示例1
输入
复制5 1 2
5 1 2
输出
复制3
3
思路: 当你拿到这个题的时候,第一印象是不是和那个猴子选大王 的题目有点类似,的确,但是感觉没另外一个麻烦哈,那么你的思是不是这个样子的 呢?
初始化一个数组且所有的元素都是0 或者其他的相同数字然后开始进行标记了,从k开始,然后到了m的时候就标记一个不同的数值,然后记得一件事情这是一个圈圈,且圈圈的人数是在减少,那么你往前走的时候,当达到某个值的时候,你要重新置零,然后重新再进行标记,这样标记几个循环之后,你就剩下一个了,也就是未被标记的那个数字,这个就是你想求得的,然后再来个循环全部数,加一个if语句,来进行输出那个下标就可以了。如果你是这个思路,请在评论区评论 1111,
其实这个思路是正确的,就是看后边的怎么执行了。如下
#include <iostream>
using namespace std;
#define N 1001
int arr[N] = { 0 };
int main()
{
int n, k, m;//严格遵守题
int cnt=0,b=0; //cnt是出局 ,b是标记
cin >> n >> k >> m;
while(cnt!=n){ //终止条件
if(k>(n-1)) k=0; //标记位置,也说明其长度不止一个
if(arr[k]==0) b++; //把循环过得给过掉
while(b==m){ //如果说到了那个标记的数字
cnt++;
b=0;
arr[k]=1;
}
k++;
}
for(int i=0;i<=n;i++){//将其不是的都排除掉
if(arr[i]==0)
cout<<i-1<<"";
}
// cout<<k-1<<"";
return 0;
}
//这个是关于猴子选大王的输出版本
n个人围成一圈,顺序排号。从第1个人开始报数 (从1到3报数),凡报到3的人退出圈子,问最后退出的顺序。
比如n为3时
退出圈子的顺序是312 //其实就是猴子选大王,但是要求把每次都的给输出
题解思路分析:
首先将全部的猴子来进行编号从1-----n个猴子
开始调用函数,函数的目的就是去晒全全部的,然后剩下最后一个猴子的作用
!!!!!
因为你的猴子的总数会逐渐的减少,因为当是3的时候那个猴子就会自动的走开
所以你要有一个终止的条件,就是总猴子数目等于减去的猴子总数加一就是只剩下一个猴子了
这个是一个大的循环条件,那么再循环内部怎样的展开呢, (不要忘记有标志位,就是当你的猴子数目等于三的时候还有计算出去的猴子数目,以及确保你的有一个在数数的人,所以就是三个标志位置)
while (a[next] == 0) //这是已经走过的的位置了’
{
next++; // 看下一个位置的猴子
if (next == n + 1) // 到尾部了,再回到头部
next = 1;//重新从1走起
}
之后要做的就是去将每一圈的3给做上标记然后让其数组的组合数字为 0 然后next继续往后边走,但是这个时候要注意就是当next==n+1的时候记得重新置零 让next=1;同时这个时候让flag=0,但是如果不是三得位置则要next继续走,然后当走到头的时候让他重新置零为 1.
flag++; // 报数号加
if (flag == 3) // 要出去了
{cout <<a[next] <<" ";//出圈的人的号码来进行输出
a[next] = 0; //关于next来对其所在的数组进行标记为0
next++; //继续走
if (next == n + 1) //当走到尾巴的时候,来拉回来
next = 1;
flag = 0;
out++; }
else{ next++;
if (next == n + 1)
next = 1; }}
猴子选大王输出版本
*记得使用全局数组或者是指针,因为这样才可以来将数组内的值输出,不然数组的值不能传递
*在三个人一组的时候,记得要你的循环要拉回来
#include <iostream>
using namespace std;
void king(int a[], int n);
int a[1000];
int main()
{
int n, i;
cin >> n;
a[0] = 0; // 0号位置没有猴子
for (i = 1; i <= n; i++)
a[i] = i;
king(a, n); //调用函数
return 0;
}
void king(int a[], int n)
{
int out = 0; // 出去了几个
int flag = 0; // 报数号
int next = 1; // 下一个
while (out < n - 1)//当out=n-1时停下来,只剩最后一个猴子,那个就是大王,这也就是停止条件
{
while (a[next] == 0)
{
next++; // 看下一个位置的猴子
if (next == n + 1) // 到尾部了,再回到头部
next = 1;
}
flag++; // 报数号加
if (flag == 3) // 要出去了
{
//
cout <<a[next] <<" ";
a[next] = 0;
next++;
if (next == n + 1)
next = 1;
flag = 0;
out++;
}
else
{
next++;
if (next == n + 1)
next = 1;
}
}
int i;
for (i = 1; i < n + 1; i++)
if (a[i] != 0) //找到最后一只猴子
cout<<i << endl;
}
两个的题其实是一摸一样的,都是来去找三个东西, 记录出去的,一直在走next 还有一个就是flag=3的时候就是要进行标记了,因为这个时候要出去了。