http://codeforces.com/problemset/problem/949/B
题目:
一开始给你一个1到n全部放在数组奇数为的数组,然后每次数组最后的一个数放入最近的空位里,然后一直循环操作直到数组没有空位。
题解:
这题可以说是规律题,我发现的规律是后面每个数第i次移动的距离都是k2(i-1),这里的k是指数字的原始位置m与2*n之间的距离。因此,当每个数字最终运动到小于n时就停止。所以有公式最终位置x=m-(2*n-m)(2t-1)<n(t是运动次数)。因此我们反推公式,可以得到m=2n-(2*n-x)/2t;(这里(2*n-x)/2t)必须处出来是整数并且被2除余1),然后用m在推导出m出数字的值就行了公式不难 看出是ans=(m+1)/2。
代码
#include<stdio.h>
#include<iostream>
using namespace std;
typedef long long ll;
ll fun(ll x,ll n)
{
ll temp=2*n-x;
while((temp&1)==0)
{
temp>>=1;
// cout<<temp<<endl;
}
return (2*n-temp+1)/2;
}
int main()
{
long long n;
int q;
scanf("%lld%d",&n,&q);
while(q--)
{
long long a;
scanf("%lld",&a);
if(a&1)
{
printf("%lld\n",(a+1)/2);
}
else
{
printf("%lld\n",fun(a,n));
}
}
}
Q.E.D.