约瑟夫环的问题
有n个人围成一圈,顺序排号,从第一个开始报数(从1到3报数),凡报到3的人退出圈子,问最后最后留下的是原来第几号的那位?
思路:
我们可以使用标志位来区分是否报到3,如果是1就说明报到3了,每次报到最后一个人的时候,我们再重新指到第一个人,这些人我们可以放在一个数组里, 这样一来,一圈下来数组会有很多0和1,第二圈继续这样,每每有一个1,循环次数就要少一次,直到只剩一个人,再遍历这个数组,打印0所在的下标,下标加1就是所求的位置。
#include <stdio.h>
int main()
{
int flag[1000]={0};
int num, persons, k = 0, i = 0;//这里k为报的数
printf("Input: \n");
scanf("%d",&num);
persons = num;
while(persons != 1)
{
if(flag[i] != 1)
{
k++;
if(k == 3)
{
persons--;
k = 0;
flag[i] = 1;
}
}
i++;
if(i == num)
{
i = 0;
}
}
for(i = 0;i < num;i++)
{
if(0 == flag[i])
{
printf("the last one is %d\n",i+1);
break;
}
}
return 0;
}
因为最近在学习C++,所以我在想是不是用容器去存会更好一些?数组毕竟有局限性,如果用不到那么多数,占用太多空间,这里我想着用vector是不是更好一些。代码改动不多,只是换了个存数的方式。
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int num, persons;
int k = 0;
printf("Input: \n");
cin>>num;
vector<int> v(num);
vector<int>::iterator it = v.begin();
persons = num;
while(persons != 1)
{
if(*it != 1)
{
k++;
if(k == 3)
{
persons--;
k = 0;
*it = 1;
}
}
it++;
if(it == v.end())
{
it = v.begin();
}
}
it = v.begin();
while(it != v.end())
{
if(!(*it))
printf("The last one is %d\n", it - v.begin() + 1);
it++;
}
return 0;
}