时间:2021/03/08
一.题目描述
给出两个不大于65535的非负整数,判断其中一个的16位二进制表示形式,是否能由另一个的16位二进制表示形式经过循环左移若干位而得到。 循环左移和普通左移的区别在于:最左边的那一位经过循环左移一位后就会被移到最右边去。比如: 1011 0000 0000 0001 经过循环左移一位后,变成 0110 0000 0000 0011, 若是循环左移2位,则变成 1100 0000 0000 0110
输入描述
每行有两个不大于65535的非负整数
输出描述
对于每一行的两个整数,输出一行,内容为YES或NO
题目链接
二.算法
题解
由于题目中说输入的数字最多为16位,而且Java中并没有循环移位的运算符,所以我们这里使用32位的int类型来存放输入数据,通过左移16位并与原数据按位或后,这32位中高16位与低16位完全相同,这样我们就可以开始移位操作了。我们要判断是否可以通过移位使两个数相同,我们需要移位的次数在0~15次之间,因为当移位16次时又回到了原数据。此时必须要进行右移(具体可以自己思考为什么),右移与0xffff按位与,这样会使数据的高16变为0,此时才能比较两个数是否相同。注意:1.开始时为左移,之后判断时为右移。2.这里使用算术移位即可,因为最多移动15次,符号位是否参与移位不重要,所以不需要使用逻辑移位。要注意在Java中逻辑移位不能用于int类型,系统会报错。
代码
import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner in = new Scanner(System.in); while(in.hasNext()){ //读取输入 int a = in.nextInt(); int b = in.nextInt(); //判断是否能够通过位运算得到 boolean flag = judge(a, b); if(flag){ System.out.println("YES"); }else{ System.out.println("NO"); } } } //判断是否能够通过位运算得到 public static boolean judge(int a, int b){ int c = (a << 16) | a; for(int i = 0; i < 16; i++){ if(((c >> i) & 0xffff) == b){ return true; } } return false; } }