1、概念
位运算符的运行速度要快于算术运算符,用位运算符代替算数符会加快程序运行速度。移位运算符包括<<(左移)和>>(右移)。左移运算符的作用是将一个二进制位的操作数按指定的移动位数向左移动,移出位被丢弃,右边的空位一律补0;右移运算符的作用是将一个二进制位的操作数按指定的移动位数向右移动,移出位被丢弃,左边的空位一律补0;
2、实例
例如:1<<1:1的二进制是0001,进行一次<<运算后,变成了0010,则1<<1的值是2。
1<<4:值为16,相当于1*2^4。
16>>3:值为2,相当于16/(2^3)。
3、例题
给出两个不大于65535的非负整数,判断其中一个的16位二进制表示形式,是否能由另一个的16位二进制表示形式经过循环左移若干位而得到。
循环左移和普通左移的区别在于:最左边的那一位经过循环左移一位后就会被移到最右边去。比如:
1011 0000 0000 0001 经过循环左移一位后,变成 0110 0000 0000 0011, 若是循环左移2位,则变成 1100 0000 0000 0110
Input
第一行是个整数n, 0 < n < 300000,表示后面还有n行数据
后面是n行,每行有两个不大于65535的非负整数
Output
对于每一行的两个整数,输出一行,内容为YES或NO
Sample Input
4 2 4 9 18 45057 49158 7 12
Sample Output
YES YES YES NO
本题中如何实现循环左移是关键,循环左移k位实际上就是将16位二进制的前k位挪到后(16-k)位的后面。则可以先将该数左移k为,再右移(16-k)位,再将得到的两个数进行或运算:
例如45057二进制为: 1011 0000 0000 0001。
循环左移3位结果是 : 1000 0000 0000 1101。
先将它左移3位得到 : 1000 0000 0000 1000,
再原数右移13位得到:0000 0000 0000 0101,
两个数再进行或运算:1000000000001101,与循环左移得到的结果是一样的。
则本题的思路是进行16次这样的位运算,如果在过程中与另一个数相等了,则输出YES,若16次后还没有得到过与另一个数相等的值,则输入NO。代码如下:
#include <stdio.h>
#include<math.h>
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
unsigned short a,b;
scanf("%hu%hu",&a,&b);
int i,m=16,flag=0;
for(i=0;i<16;i++)
{
a=(a<<i)|(a>>(16-i));
if(a==b)
{
flag=1;
printf("YES\n");
break;
}
}
if (!flag)
printf("NO\n");
}
}