CF——1475A - Odd Divisor

题目

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");
        }
    }
}

结果

就是这种转化的思想还是挺好的,感觉挺神奇的,脑子一灵光,就想到了这种方法,也算是瞎猫碰上死耗子了吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值