cj搜索算法-魔版(打表术失败总结)

今天碰到一个搜索题,题目是:

7.5  魔板

【问题描述】

    有这样一种魔板:它是一个长方形的面板,被划分成n行m列的n*m个方格。每个方格内有一个小灯泡,灯泡的状态有两种(亮或暗)。我们可以通过若干操作使魔板从一个状态改变为另一个状态。操作的方式有两种:

    (1)任选一行,改变该行中所有灯泡的状态,即亮的变暗、暗的变亮;

    (2)任选两列,交换其位置。

    当然并不是任意的两种状态都可以通过若干操作来实现互相转化的。

    你的任务就是根据给定两个魔板状态,判断两个状态能否互相转化。

【输入】

    文件中包含多组数据。第一行一个整数k,表示有k组数据。

    每组数据的第一行两个整数n和m。(0<n,m≤100)

    以下的n行描述第一个魔板。每行有m个数字(0或1),中间用空格分隔。若第x行的  第y个数字为0,则表示魔板的第x行y列的灯泡为“亮”;否则为“暗”。

    然后的n行描述第二个魔板。数据格式同上。

    任意两组数据间没有空行。

【输出】

    共k行,依次描述每一组数据的结果。

    若两个魔板可以相互转化,则输出YES,否则输出NO。(注意:请使用大写字母)

【样例】

    panel.in

    2

    3 4

    0 1 0 1

    1 0 0 1

    0 0 0 0           

    0 1 0 1

失败总结:

最最主要的是,偷懒,选择了打表术.....一开始觉得打表术简单,结果是很多情况都没有考虑到,整节晚自习都在考虑完善打表术,结果后面发现打表术根本行不通!

详细:

     1.一开始以为只要每行的0的个数符合一定条件就可以了,但是发现列也要改;

  2.以为列0的数量符合条件就好了,结果发现顺序也是个问题;

      3.用string改好顺序了,结果发现判断并不容易;

  4.判断好了,发现 如果一行的0的个数等于m div 2 时,要分类讨论..............

  然后,就超级复杂........

教训:碰到搜索题最好不要用打表术!如果用打表术一定要考虑周全!

不要偷懒!不要鼠目寸光!!!!!!!!!

附:我的失败代码:

 1 program panel;
 2 var
 3    s:array[1..200,1..200] of integer;
 4    jin:array[1..200]of integer;
 5    num2,num3:array[1..200]of string;
 6    st1,st2:string;
 7    w:array[1..200] of longint;
 8    boo:array[1..200]of boolean;
 9    num:array[1..200] of longint;
10    i,j,k,l,h,m,n,q,t:longint;
11    bool,bool2:boolean;
12 begin
13         assign(input,'panel.in');
14         assign(output,'panel.out');
15         reset(input);
16         rewrite(output);
17         read(k);
18         for q:=1 to k do
19         begin
20         fillchar(s,sizeof(s),0);
21         fillchar(num,sizeof(num),0);
22         bool:=true;
23         read(n,m);
24         for i:=1 to 2*n do
25                 for j:=1 to m do
26                 begin
27                         read(s[i,j]);
28                         if s[i,j]=0 then inc(num[i]);
29                 end;
30         i:=1;
31         while((num[i]=num[i+n])or(num[i]+num[i+n]=m))and(i<=n)do
32         begin
33                 inc(i);
34                 if ((num[i]<>num[i+n])and(num[i]+num[i+n]<>m))and(i<=n)
35                 then bool:=false;
36         end;
37         if not bool then writeln('NO')
38         else
39                 begin
40                 h:=0;
41                 for i:=1 to n do
42                         if num[i]=m div 2 then begin inc(h); w[h]:=i; end;
43                 for i:=1 to n do
44                         begin
45                         if (num[i]<>num[i+n])and(num[i]+num[i+n]=m) then
46                                 begin
47                                 for j:=1 to m do
48                                         if s[i,j]=0 then s[i,j]:=1
49                                                 else s[i,j]:=0;
50                                 end;
51                         end;
52                 bool2:=true;
53                 for i:=1 to m do
54                         delete(num2[i],1,length(num2[i]));
55                 for i:=1 to m do
56                         delete(num3[i],1,length(num3[i]));
57                 for j:=1 to m do
58                         for i:=1 to n do
59                                 num2[j]:=num2[j]+chr(s[i,j]+48);
60                 for j:=1 to m do
61                         for i:=n+1 to 2*n do
62                                 num3[j]:=num3[j]+chr(s[i,j]+48);
63                 j:=0;
64                 fillchar(boo,sizeof(boo),true);
65                 bool2:=true;
66                 repeat
67                         inc(j);
68                         t:=0;
69                         repeat
70                         inc(t);
71                         if (num2[j]=num3[t])and(boo[t])then boo[t]:=false;
72                         until((num2[j]=num3[t]))or(t>=m);
73                         if (num2[j]<>num3[t])and(j<=m)
74                         then bool2:=false;
75                 until (num2[j]<>num3[t]) or (j>=m);
76                 if not bool2 then
77                                 begin
78                                 inc(jin[1]);
79                                 e:=1;
80                                 while jin[e]=2 do begin jin[e]:=0; inc(e); inc(jin[e]) end;
81                                 if w[h+1]=1 then write('NO')
82                                 else begin
83                                         for i:=1 to h do
84                                                 if w[h]=1 then
85                                                                 begin{到这里就变得很复杂了!}
86                                         end;
87                                 end;
88                 else writeln('YES');
89                 end;
90                 end;
91         close(input);
92         close(output);
93 end.    

记住教训啊!

2012-10-09

 

posted @ 2012-10-09 22:29  改名字干什么  阅读(214)  评论(0编辑  收藏  举报