P党写几小时的程序 C++才几行……
首先P的位运算有上限2^30 此时 即便是 int64也会因为补码坑死人的
到1 shl 31时 int64 是负数 故 这个时候 不能shr 为多出好多位
造成以上结果的真正原因是 shl 和 shr 只支持到1 shl 30 (Longint)所以在int64或qword会出错 要自己写
C党读入方法 %x 表示 二进制
#include<cstdio> using namespace std; int r,x,y; int main() { scanf("%x,%d,%d",&r,&x,&y); r=r&(~(1<<x)); r=r&(~(1<<y-2)); r=r|(1<<(y-1))|(1<<(y)); printf("%xn",r); }
P党取到30的做法:
Program P3748; const // ordA=65; orda=97; ord0=48; var s:string; r:qword; x,y:longint; function turn2(c:char):longint; begin if ord(c)>=orda then begin exit(ord(c)-orda+10); end else exit(ord(c)-ord0); end; function turn16(x:qword):longint; begin if (x<>0) then begin turn16:=x and 15; x:=x shr 4; turn16(x); if turn16<=10 then write(turn16) else write(chr(turn16-10+orda)); end; end; function cin:longint; var i:longint; s1:string; begin i:=1; while s[i]<>',' do inc(i); s1:=copy(s,1,i-1); val(s1,cin); delete(s,1,i); end; function cin16:qword; var i,j:longint; s1:string; begin i:=1; while s[i]<>',' do inc(i); s1:=copy(s,1,i-1); cin16:=0; for j:=1 to i-1 do cin16:=cin16 shl 4+turn2(s1[j]); delete(s,1,i); end; begin readln(s); r:=cin16;x:=cin;val(s,y); r:=r and (not (1 shl x)); r:=r and (not (1 shl (y-2))); r:=r or (1 shl (y-1)); r:=r or (1 shl y); turn16(r); writeln; end.
更正AC版:
Program P3748; const // ordA=65; orda=97; ord0=48; var s:string; r,k:qword; x,y,i:longint; function turn2(c:char):longint; begin if ord(c)>=orda then begin exit(ord(c)-orda+10); end else exit(ord(c)-ord0); end; function turn16(x:qword):longint; begin if (x<>0) then begin turn16:=x and 15; x:=x div 16; turn16(x); if turn16<=10 then write(turn16) else write(chr(turn16-10+orda)); end; end; function cin:longint; var i:longint; s1:string; begin i:=1; while s[i]<>',' do inc(i); s1:=copy(s,1,i-1); val(s1,cin); delete(s,1,i); end; function cin16:qword; var i,j:longint; s1:string; begin i:=1; while s[i]<>',' do inc(i); s1:=copy(s,1,i-1); cin16:=0; for j:=1 to i-1 do cin16:=cin16 shl 4+turn2(s1[j]); delete(s,1,i); end; function shl2(x:longint):qword; var i:longint; begin shl2:=1; for i:=1 to x do shl2:=shl2*2; end; begin readln(s); r:=cin16;x:=cin;val(s,y); r:=r and (not (shl2(x))); r:=r and (not (shl2(y-2))); r:=r or (shl2(y-1)); r:=r or (shl2(y)); turn16(r); writeln; end.
附:
功能 | 示例 | 位运算
----------------------+---------------------------+--------------------
去掉最后一位 | (101101->10110) | x shr 1
在最后加一个0 | (101101->1011010) | x shl 1
在最后加一个1 | (101101->1011011) | x shl 1+1
把最后一位变成1 | (101100->101101) | x or 1
把最后一位变成0 | (101101->101100) | x or 1-1
最后一位取反 | (101101->101100) | x xor 1
把右数第k位变成1 | (101001->101101,k=3) | x or (1 shl (k-1))
把右数第k位变成0 | (101101->101001,k=3) | x and not (1 shl (k-1))
右数第k位取反 | (101001->101101,k=3) | x xor (1 shl (k-1))
取末三位 | (1101101->101) | x and 7
取末k位 | (1101101->1101,k=5) | x and (1 shl k-1)
取右数第k位 | (1101101->1,k=4) | x shr (k-1) and 1
把末k位变成1 | (101001->101111,k=4) | x or (1 shl k-1)
末k位取反 | (101001->100110,k=4) | x xor (1 shl k-1)
把右边连续的1变成0 | (100101111->100100000) | x and (x+1)
把右起第一个0变成1 | (100101111->100111111) | x or (x+1)
把右边连续的0变成1 | (11011000->11011111) | x or (x-1)
取右边连续的1 | (100101111->1111) | (x xor (x+1)) shr 1
去掉右起第一个1的左边 | (100101000->1000) | x and (x xor (x-1))