#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <math.h>
using namespace std;
int main(){
int num;
scanf("%d",&num);
for(int i=0;i<num;i++){
int m;
scanf("%d",&m);
int l=m;
int layer=1;
//找出给节点的最左父节点
;
while(pow(2.0,(double)layer-1)<=m)
layer++;
//if(pow(2,layer-1)>m){
layer--;
// }
int p=pow(2.0,(double)layer-1);
// printf("fsfda%d %d\n",p,layer);
//找到l
while(p!=m){
layer--;
if(p>m){
p=p-pow(2.0,(double)layer-1);
}
else
{
p=p+pow(2.0,(double)layer-1);
}
}
// printf("%d %d\n",layer,p);
int layernow=layer;
while(layer>1){
p=p-pow(2.0,(double)layer-2);
layer--;
}
printf("%d %d\n",p,m+m-p);
}
return 0;
}
有更简单的方法:
下面是利用神奇的X &(-X) ( 求X最低位的1,等于2^(x的因子2的个数) ),当时看完之后我就无语了。。。十行写完
#include<stdio.h> #include<stdlib.h> #include<string.h> int main() { int T, x; for(scanf("%d", &T); T --; ) { scanf("%d", &x); printf("%d %d\n", x - (x & (- x)) + 1, x + (x & (- x)) - 1); } return 0; }