题目
You are given an integer n. Check if n has an odd divisor, greater than one (does there exist such a number x (x>1) that n is divisible by x and x is odd).
For example, if n=6, then there is x=3. If n=4, then such a number does not exist.
Input
The first line contains one integer t (1≤t≤10^4) — the number of test cases. Then t test cases follow.
Each test case contains one integer n (2≤n≤10^14).
Please note, that the input for some test cases won’t fit into 32-bit integer type, so you should use at least 64-bit integer type in your programming language.
Output
For each test case, output on a separate line:
“YES” if n has an odd divisor, greater than one;
“NO” otherwise.
You can output “YES” and “NO” in any case (for example, the strings yEs, yes, Yes and YES will be recognized as positive).
题目传送门
翻译:大意就是先给你一个测试例子的数目t,代码要接收t个测试例子,在每个例子里,都要接收一个数字n,并且提示了你这个n要存放在64位的整形数中,因为数字的范围最大可以到10的14次方。如果这个数有一个奇数的因数,就输出"YES",否则输出"NO"。
思路
判断一个数,是否有奇数的因子,这个很难。但是,判断一个数,是否全部都是偶数的因子,那就简单得多了。假设一个数的所有因子都是偶数,那么它一定是2的k次方,即这个数一定可以分解成k个2相乘,不然就会出现奇数。
所以,问题就转化为了,一个数,是否是2的k次幂。那么我们怎么判断一个数是否是2的k次幂呢,我们都知道,计算机中的数值存储是用二进制形式来存放的。如果一个数是2的k次幂,那么这个数的二进制形式只有1个1.只要将这个数的二进制形式1的个数计算一下,如果出现了2个或者以上的1,那么这个数就不是2的n次幂,那么就一定有奇数因子。
代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner reader=new Scanner(System.in);
int t=reader.nextInt();//测试例子数目
for (int i=0;i<t;++i)
{
long test= reader.nextLong();//接收测试的数字
int count=0;
while (test>0)
{
//计算有多少个1
if ((test&1)==1)
++count;
if (count>1)
break;
test>>=1;//向左移动一位,相当于除以2
}
if (count==1)
System.out.println("NO");
else
System.out.println("YES");
}
}
}
结果
就是这种转化的思想还是挺好的,感觉挺神奇的,脑子一灵光,就想到了这种方法,也算是瞎猫碰上死耗子了吧。