zoukankan      html  css  js  c++  java
  • 1050 棋盘染色 2


    题目描述 Description

        有一个5*N的棋盘,棋盘中的一些格子已经被染成了黑色,你的任务是对最少的格子染色,使得所有的黑色能连成一块。

    输入描述 Input Description

        第一行一个整数N(<=100),接下来N行每行一个长度为5的01串,1表示所在格子已经被染成了黑色,0表示所在格子没有被染色。

    输出描述 Output Description

        第一行一个整数N(<=100),接下来N行每行一个长度为5的01串,1表示所在格子已经被染成了黑色,0表示所在格子没有被染色。

    样例输入 Sample Input

        5
        11100
        11000
        10000
        01111
        11111

    样例输出 Sample Output

        1

    数据范围及提示 Data Size & Hint

        N(<=100)

    写得要吐了,看了Wikioi后面的题解突然有了灵感(看到了时间复杂度和空间复杂度.....)

    状压dp,每一行压连通性,因为只有5列,最多有三个互不相交的联通块,所以可以用4进制来表示每一行的状态表示(每一位表示这一格属于第几个联通块)

    因为所有的黑色块都必须联通,所以上面的每一个不同的联通块至少有一个要延伸到下面来,这个转移的时候注意一下

    对于每一个状态,枚举要下一层涂黑哪些块,然后转移,最后一层黑色都属于同一联通块才能更新答案

     (这个代码其实是错的...下面还有一个)

      1 const
      2     maxn=102;
      3 type
      4     node=record
      5       x,y:longint;
      6     end;
      7     aa=array[0..5]of longint;
      8 var
      9     f:array[0..maxn,0..1204]of longint;
     10     a:array[0..maxn]of longint;
     11     n:longint;
     12 
     13 procedure init;
     14 var
     15     i,j:longint;
     16     s:char;
     17 begin
     18     readln(n);
     19     for i:=1 to n do
     20       begin
     21         for j:=1 to 5 do
     22           begin
     23             read(s);
     24             a[i]:=a[i]<<1+ord(s)-ord('0');
     25           end;
     26         readln;
     27       end;
     28     while n>0 do
     29       begin
     30         if a[n]>0 then break;
     31         dec(n);
     32       end;
     33     if n=0 then
     34     begin
     35       write(0);
     36       halt;
     37     end;
     38 end;
     39 
     40 procedure get(var a:aa);
     41 var
     42     i,j,k,c:longint;
     43 begin
     44     c:=1;
     45     for i:=1 to 3 do
     46       for j:=1 to 5 do
     47         if a[j]=i then
     48         begin
     49           if i=c then inc(c);
     50           k:=j;
     51           while (k>1) and (a[k-1]>0) do
     52             begin
     53               dec(k);
     54               a[k]:=i;
     55             end;
     56           k:=j;
     57           while (k<5) and (a[k+1]>0) do
     58             begin
     59               inc(k);
     60               a[k]:=i;
     61             end;
     62         end;
     63     dec(c);
     64     for i:=1 to 5 do
     65       if a[i]=4 then
     66       begin
     67         if a[i-1]>0 then a[i]:=c
     68         else
     69           begin
     70              inc(c);
     71              a[i]:=c;
     72           end;
     73       end;
     74 end;
     75 
     76 function bit(x:longint):longint;
     77 begin
     78     if x=0 then exit(0);
     79     exit(bit(x-(x and -x))+1);
     80 end;
     81 
     82 var
     83     q:array[0..maxn*1024]of node;
     84 
     85 procedure work;
     86 var
     87     head,tail,i,j,k,ans,save:longint;
     88     s,t:aa;
     89     flag:boolean;
     90 begin
     91     fillchar(f,sizeof(f),1);
     92     t[0]:=0;
     93     ans:=500;
     94     f[0,0]:=0;
     95     q[1].x:=0;
     96     q[1].y:=0;
     97     head:=1;
     98     tail:=1;
     99     while head<=tail do
    100       begin
    101         save:=q[head].y;
    102         for i:=1 to 5 do
    103           begin
    104             s[i]:=q[head].y and 3;
    105             q[head].y:=q[head].y>>2;
    106           end;
    107         q[head].y:=save;
    108         if q[head].x=n then
    109         begin
    110           flag:=true;
    111           for i:=1 to 5 do
    112             if s[i]>1 then flag:=false;
    113           if flag then
    114           if ans>f[q[head].x,q[head].y] then ans:=f[q[head].x,q[head].y];
    115           inc(head);
    116           continue;
    117         end;
    118         for i:=0 to 31 do
    119           if i and a[q[head].x+1]=0 then
    120           begin
    121             for j:=1 to 5 do
    122               t[j]:=(((a[q[head].x+1]+i)>>(j-1))and 1)*4;
    123             k:=0;
    124             for j:=1 to 5 do
    125               if (s[j]>0) and (t[j]>0) then
    126               begin
    127                 t[j]:=s[j];
    128                 k:=k or (1<<s[j]);
    129               end;
    130             flag:=true;
    131             for j:=1 to 5 do
    132               if (s[j]>0) and (k and (1<<s[j])=0) then flag:=false;
    133             if flag=false then continue;
    134             get(t);
    135             k:=0;
    136             for j:=5 downto 1 do
    137               k:=k<<2+t[j];
    138             if f[q[head].x+1,k]>500 then
    139             begin
    140               inc(tail);
    141               q[tail].x:=q[head].x+1;
    142               q[tail].y:=k;
    143             end;
    144             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);
    145           end;
    146         inc(head);
    147       end;
    148     write(ans);
    149 end;
    150 
    151 begin
    152     init;
    153     work;
    154 end.
    View Code

    为什么会错呢,我写这个的时候,头脑有点乱,导致少考虑了一种情况(因为转移的时候联通块我是乱搞的)

    2

    11101

    10111

    这个我就会错

    上面我是用10222表示的,然后转移到下面

    就变成了14202然后把1附近的改成1(下一行的我全部用4来表示),就变成了11102,结果就错了

    下面是改正后的代码

    感谢zkyTimeMachine的帮助,查出了这个不易发现的错误,对于前面那个代码AC了我只能说数据太弱,刚好没出到这种数据

      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.
    View Code
  • 相关阅读:
    LeetCode Missing Number (简单题)
    LeetCode Valid Anagram (简单题)
    LeetCode Single Number III (xor)
    LeetCode Best Time to Buy and Sell Stock II (简单题)
    LeetCode Move Zeroes (简单题)
    LeetCode Add Digits (规律题)
    DependencyProperty深入浅出
    SQL Server存储机制二
    WPF自定义RoutedEvent事件示例代码
    ViewModel命令ICommand对象定义
  • 原文地址:https://www.cnblogs.com/Randolph87/p/3631598.html
Copyright © 2011-2022 走看看