您的位置:首页 > 其它

高斯消元解xor方程 回带出解 poj3185

2011-05-26 16:31 211 查看
同1830,有关联系数为1,最后一列是是否要改变。

由于题目要使元为1的尽量少,所以还要通过枚举解进行比较。

我是用搜索进行枚举,将之前结果回带后,不定元行为(0,0,0,0....0)则有该元为1和0两种情况,为0时要改为(0,0,...1,....0)方便之后进行回带消元,否则为1则(0,0,0...1...1);若为(0,0,0...0....1)则确定该元为1,改为(0,0,0...1...1)。

最终解为最后一列为1的个数。

var ans,n:longint;
    a,a1:array[0..22]of longint;
procedure check(j:longint);
var a1:array[0..22]of longint;
    i,k,tot:longint;
begin
 a1:=a;
 for i:=j-1 downto 1 do
  for k:=n downto i+1 do
   if a[i]>>k and 1=1 then a[i]:=a[i] xor a[k];
 tot:=0;
 for i:=1 to n do tot:=tot+a[i] and 1;
 if tot<ans then ans:=tot;
 a:=a1
end;
procedure dfs(x,y:longint);
var i,ne:longint;
begin
 if x<y then begin check(y);exit end;
 ne:=a[x];
 for i:=n downto x+1 do
  if a[x]>>i and 1=1 then a[x]:=a[x] xor a[i];
 if a[x] and 1=1 then begin
  a[x]:=a[x]+1<<x;dfs(x-1,y);
 end
 else begin
  a[x]:=1<<x;dfs(x-1,y);a[x]:=1<<x+1;dfs(x-1,y)
 end;
 a[x]:=ne
end;
procedure init;
var i,j,k,l:longint;
begin
 n:=20;
 for i:=1 to n do begin read(a[i]);a[i]:=a[i] or 1<<i end;
 a[1]:=a[1] or 1<<2;
 for i:=2 to n-1 do a[i]:=a[i] or 1<< (i-1) or 1<< (i+1);
 a
:=a
 or 1<<(n-1);
 j:=1;ans:=0;
 for i:=1 to n do begin
  k:=j;
  while (a[k]>>i and 1=0)and(k<=n) do inc(k);
  if k<=n then begin
   a[0]:=a[k];a[k]:=a[j];a[j]:=a[0];
   for l:=j+1 to n do
    if a[l]>>i and 1=1 then a[l]:=a[l] xor a[j];
   inc(j)
  end
 end;
 ans:=maxlongint;
 if a
=0 then begin
  a
:=1<<20+1;a1:=a;
  dfs(n-1,j);
  a:=a1;a
:=1<<20;
  dfs(n-1,j)
 end
 else begin
  ans:=1;
  for i:=n-1 downto 1 do begin
   for j:=n downto i+1 do
    if a[i]>>j and 1=1 then a[i]:=a[i] xor a[j];
   ans:=ans+a[i] and 1
  end
 end;
 writeln(ans)
end;
begin
assign(input,'3185.in');reset(input);
 init;
close(input)
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: