题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3668
OR,XOR,AND都是位运算,其运算结果相当于转化成二进制之后每位分别进行该项位运算,每位之间是相互独立,不存在进位,而在二进制下只存在0/1,所以可以把它看成一个二进制数,从最高位开始扫,每一位分别用0/1试一下是否可行,每次取当前位在合法情况下尽可能的大值(即尽可能取1),因为是从最高位开始扫,所以答案一定是最大值,然后按位乘上权重相加就是答案。
贴代码:
var a,b:array[0..100005]of longint;
n,m,ans,sum:longint;
procedure init;
var i,j,x:longint;
ch,ch1,ch2:char;
begin
assign(input,'sleep.in');reset(input);
assign(output,'sleep.out');rewrite(output);
readln(n,m);
for i:=1 to n do
begin
read(ch);
case ch of
'A':begin
readln(ch,ch1,ch2,x);
a[i]:=0;b[i]:=x;
end;
'O':begin
readln(ch,ch1,x);
a[i]:=1;b[i]:=x;
end;
'X':begin
readln(ch,ch1,ch2,x);
a[i]:=2;b[i]:=x;
end;
end;
end;
end;
function work(x,y,z:longint):longint;
begin
case z of
0:exit(x and y);
1:exit(x or y);
2:exit(x xor y);
end;
end;
procedure main;
var bo,x1,x2,k,i,j,step:longint;
begin
step:=31;
ans:=0;sum:=0;
for i:=step downto 1 do
begin
bo:=0;x1:=0;x2:=1;
if sum+(1<<(i-1))>m then bo:=1;
for j:=1 to n do
begin
k:=0;
if b[j] and (1<<(i-1))=1<<(i-1) then k:=1;
x1:=work(x1,k,a[j]);
x2:=work(x2,k,a[j]);
end;
if bo=1 then ans:=ans+x1*(1<<(i-1))
else begin
if x1=1 then ans:=ans+(1<<(i-1))
else if x2=1 then begin ans:=ans+(1<<(i-1));sum:=sum+(1<<(i-1)); end;
end;
end;
end;
procedure print;
begin
writeln(ans);
close(input);close(output);
end;
begin
init;
main;
print;
end.
【写的有漏洞的,欢迎路过大神吐槽】
2017/2/13 18:59:00
Ending.