codevs天梯 棋盘染色2

来源:互联网 发布:电脑里编程开发 编辑:程序博客网 时间:2024/05/06 05:21
有一个5*N的棋盘,棋盘中的一些格子已经被染成了黑色,你的任务是对最少的格子染色,使得所有的黑色能连成一块。
分析:这题很容易想到是广搜,但数据那么大,如果一个一个点来更新就gg了==。所以开出一个树状数组对最大块进行预处理,剩下就没什么好说的了。
  1.  const
  2.        maxn=102;
  3.    type
  4.        node=record
  5.          x,y:longint;
  6.       end;
  7.       aa=array[0..6]of longint;
  8.    var
  9.        f:array[0..maxn,0..1204]of longint;
  10.       a:array[0..maxn]of longint;
  11.       fa:array[1..4]of longint;
  12.       flag:array[1..4]of boolean;
  13.       n:longint;
  14.   
  15.   procedure init;
  16.   var
  17.       i,j:longint;
  18.       s:char;
  19.   begin
  20.       readln(n);
  21.       for i:=1 to n do
  22.         begin
  23.           for j:=1 to 5 do
  24.             begin
  25.               read(s);
  26.               a[i]:=a[i]<<1+ord(s)-ord('0');
  27.             end;
  28.           readln;
  29.        end;
  30.       while n>0 do
  31.         begin
  32.           if a[n]>0 then break;
  33.           dec(n);
  34.         end;
  35.       if n=0 then
  36.       begin
  37.         write(0);
  38.         halt;
  39.       end;
  40.   end;
  41.   
  42.   procedure change(var a:aa;b,c:longint);
  43.   var
  44.       i:longint;
  45.   begin
  46.       for i:=1 to 5 do
  47.         if a[i]=b then
  48.         begin
  49.          a[i]:=c;
  50.          if (a[i-1]<>0) and (a[i-1]<10) then change(a,a[i-1],c);
  51.           if (a[i+1]<>0) and (a[i+1]<10) then change(a,a[i+1],c);
  52.         end;
  53.   end;
  54.   
  55.   procedure get(var a:aa);
  56.   var
  57.       i,c:longint;
  58.   begin
  59.       c:=10;
  60.       for i:=1 to 5 do
  61.        if (a[i]<>0) and (a[i]<10) then
  62.         begin
  63.           inc(c);
  64.           change(a,a[i],c);
  65.        end;
  66.       for i:=1 to 5 do
  67.         if a[i]>0 then dec(a[i],10);
  68.   end;
  69.   
  70.   function bit(x:longint):longint;
  71.   begin
  72.       if x=0 then exit(0);
  73.       exit(bit(x-(x and -x))+1);
  74.   end;
  75.   
  76.   var
  77.      q:array[0..maxn*1024]of node;
  78.   
  79.   procedure work;
  80.   var
  81.       head,tail,i,j,k,ans,save:longint;
  82.       s,t:aa;
  83.       flag:boolean;
  84.   begin
  85.       fillchar(f,sizeof(f),1);
  86.       t[0]:=0;
  87.       t[6]:=0;
  88.      ans:=500;
  89.       f[0,0]:=0;
  90.       q[1].x:=0;
  91.       q[1].y:=0;
  92.       head:=1;
  93.       tail:=1;
  94.       while head<=tail do
  95.         begin
  96.           save:=q[head].y;
  97.           for i:=1 to 5 do
  98.             begin
  99.               s[i]:=q[head].y and 3;
  100.              q[head].y:=q[head].y>>2;
  101.            end;
  102.          q[head].y:=save;
  103.          if q[head].x=n then
  104.          begin
  105.            flag:=true;
  106. for i:=1 to 5 do
  107.              if s[i]>1 then flag:=false;
  108.            if flag then
  109.            if ans>f[q[head].x,q[head].y] then ans:=f[q[head].x,q[head].y];
  110.            inc(head);
  111.            continue;
  112.          end;
  113.          for i:=0 to 31 do
  114.            if i and a[q[head].x+1]=0 then
  115.            begin
  116.              for j:=1 to 5 do
  117.                t[j]:=(((a[q[head].x+1]+i)>>(j-1))and 1)*(j+3);
  118.              k:=0;
  119.             for j:=1 to 5 do
  120.               if (s[j]>0) and (t[j]>0) then
  121.                begin
  122.                 t[j]:=s[j];
  123.                  k:=k or (1<<s[j]);
  124.               end;
  125.              flag:=true;
  126.              for j:=1 to 5 do
  127.               if (s[j]>0) and (k and (1<<s[j])=0) then flag:=false;
  128.              if flag=false then continue;
  129.              get(t);
  130.              k:=0;
  131.             for j:=5 downto 1 do
  132.                k:=k<<2+t[j];
  133.             if f[q[head].x+1,k]>500 then
  134.             begin
  135.              inc(tail);
  136.               q[tail].x:=q[head].x+1;
  137.               q[tail].y:=k;
  138.             end;
  139.              if f[q[head].x+1,k]>f[q[head].x,q[head].y]+bit(i) then f[q[head].x+1,k]:=f[q[head].x,q[head].y]+bit(i);
  140.           end;
  141.         inc(head);
  142.      end;
  143.      write(ans);
  144.  end;
  145.  
  146.  begin
  147.      init;
  148.      work;
  149.  end.

1 0