Description
Input
Output
Sample Input
2
8
10
Sample Output
1 15
9 11
这也是一道很有意思的水题~
我发现第n层上(n=0,1,2……)的数字分别为2^n+2^(n+1)*k~由此就可以计算出每个数所在层数~
而根节点与最大数和最小数之间相差sigma 2^k- (k=0,1,2……n-1)~
所以代码如下~
#include"stdio.h"
int main()
{
int n;
int x;
int i,j;
int count;
int lc,rc;
int s;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&x);
count=0;
lc=rc=x;
s=1;
for(;;)
{
if(x%2!=0)
break;
x=x/2;
count++;
}
for(j=0;j<count;j++)
{
lc=lc-s;
rc=rc+s;
s*=2;
}
printf("%d %d\n",lc,rc);
}
return 0;
}带看完discuss之后~我发现更简单的方法~利用树状数组思想中的位运算~
最小值就是该数用二进制表示后将其中的最后一个1挪到最后一位~
最大值就是将最后一个1后面全赋为1~
利用分别利用x-(x&(-x))+1和x+(x&(-x))-1就可以实现~
注意~(-x)表示将x取反后加1~
在位运算中还需注意~符号^是异或的意思~
下面是代码~要简洁许多~
#include"stdio.h"
int main()
{
int n;
int x;
scanf("%d",&n);
while(n--)
{
scanf("%d",&x);
printf("%d %d\n",x-(x&(-x))+1,x+(x&(-x))-1);
}
}