20110805组队赛c题

来源:互联网 发布:linux中安装oracle11g 编辑:程序博客网 时间:2024/06/05 11:11

Description

026城市的大尾巴狼和秃尾巴狼是好朋友,有一天,秃尾巴狼给大尾巴狼说了有关约瑟夫环的问题:n个编号依次为1,2....n的人站成一个圈,他们按序号大小顺时针的站着.然后从1号开始报数,报到2的人就会被杀掉,然后再从1开始报数.直到只剩下一个人为止.剩下这个人的编号我们定义为J(n).我们可以知到J(1)=1,J(5)=3,J(6)=5.大尾巴狼开始冥思苦想起来.突然他发现,如果每次用J(n)当成现在的n的话,那么最后会得到一个fixed number.比如说J(2)=1.J(J(2))=1,J(J(J(...J(2)...)))=1.秃尾巴同意大尾巴狼的这个想法,但是大尾巴狼还是不满足,他想知道对于一个给定的n,那么最后会得到的fixed number是多少呢.你能帮助大尾巴狼同学吗?

Input

有多组测试数据
每组数据一行,包含一个数字n(1<=n<=10^26).n=0表示输入结束

Output

每组数据输出一行,包含一个数K,使得J(J(J(J...J(n)...)))=K,而且J(K)=K

Sample Input

1060

Sample Output

33


这道题是关于约瑟夫环的~

我们可知~对于约瑟夫环~

j(2*n)=2*j(n)-1;

j(2*n+1)=2*j(n)+1;

即对于j(n)~若n=2^m+r~(m为最大值~) 

j(n)=2*r+1;

则~若将j(n)与n转换为二进制~n为j(n)向左移一位~

例如~j(10)=5~

10的二进制为1010~5的二进制为0101~

所以~要求的使j(n)=n的数~一定是全为1的数~即左移不会使数值改变~

则只用求n化为二进制时1的个数~若有count个~

则所求的数的二进制形式为count个连1~

再化为十进制即可~

但这道题数值最大达到了10^26~若要用cpp~long long不能满足~需要高精度~有点麻烦~用java的biginteger则可以直接做~

这里我没有用高精度~只是单纯的记下这种方法而已~

#include"cstdio"#include"math.h"int main(){long long a;int count;long long b;while(scanf("%lld",&a)!=EOF){count=0;while(a){a=a&(a-1);count++;}//求1的个数~b=pow(2.0,count)-1;printf("%lld\n",b);}}

原创粉丝点击