题目描述
约瑟夫问题(https://baike.baidu.com/item/约瑟夫问题),n个人,1 2报数 1出队( 就是体育课的时候1 2报数 1出队,2留下),q次询问,每次求第x个人是第几个出队的
输入描述:
第一行两个数n,q 接下来q行,每行一个数x,表示询问
输出描述:
一行输出一个询问的答案
示例1
输入
4 3 2 3 4
输出
3 2 4
思路:我们发现每次都是位于奇数位置的人出队,所以对于某个人第几次出队,只需要关心每次轮到他的时候他是不是位于奇数位置.
代码:
#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define mod 1000000007
using namespace std;
typedef long long ll;
const int maxn = 2e5+5;
const double esp = 1e-12;
const int ff = 0x3f3f3f3f;
map<int,int>::iterator it;
ll n,q;
int main()
{
cin>>n>>q;
while(q--)
{
ll x;
scanf("%lld",&x);
//x是每次轮转他所在的位置
ll ans = 0;
ll sum = n;//当前总人数
while(x%2 == 0)
{
ll d = x/2; //出队的人数
ans+= d;
x = sum-d;//更新他的位置
sum = sum-d;//更新总人数
}
ans+= (x+1)/2;//一旦位于奇数位就要出队
printf("%lld\n",ans);
}
return 0;
}