今天碰到乙個搜尋題,題目是:
7.5 魔板
【問題描述】
有這樣一種魔板:它是乙個長方形的面板,被劃分成n行m列的n*m個方格。每個方格內有乙個小燈泡,燈泡的狀態有兩種(亮或暗)。我們可以通過若干操作使魔板從乙個狀態改變為另乙個狀態。操作的方式有兩種:
(1)任選一行,改變該行中所有燈泡的狀態,即亮的變暗、暗的變亮;
(2)任選兩列,交換其位置。
當然並不是任意的兩種狀態都可以通過若干操作來實現互相轉化的。
你的任務就是根據給定兩個魔板狀態,判斷兩個狀態能否互相轉化。
【輸入】
檔案中包含多組資料。第一行乙個整數k,表示有k組資料。
每組資料的第一行兩個整數n和m。(0以下的n行描述第乙個魔板。每行有m個數字(0或1),中間用空格分隔。若第x行的 第y個數字為0,則表示魔板的第x行y列的燈泡為「亮」;否則為「暗」。
然後的n行描述第二個魔板。資料格式同上。
任意兩組資料間沒有空行。
【輸出】
共k行,依次描述每一組資料的結果。
若兩個魔板可以相互轉化,則輸出yes,否則輸出no。(注意:請使用大寫字母)
【樣例】
panel.in
3 40 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 時,要分類討論..............
然後,就超級複雜........
教訓:碰到搜尋題最好不要用打表術!如果用打表術一定要考慮周全!
不要偷懶!不要鼠目寸光!!!!!!!!!
附:我的失敗**:
1program
panel;
2var
3 s:array[1..200,1..200] of
integer;
4 jin:array[1..200]of
integer;
5 num2,num3:array[1..200]of
string;
6st1,st2:string;
7 w:array[1..200] of
longint;
8 boo:array[1..200]of
boolean;
9 num:array[1..200] of
longint;
10i,j,k,l,h,m,n,q,t:longint;
11bool,bool2:boolean;
12begin
13 assign(input,'
panel.in');
14 assign(output,'
panel.out');
15reset(input);
16rewrite(output);
17read(k);
18for q:=1
to k do
19begin
20 fillchar(s,sizeof(s),0
);21 fillchar(num,sizeof(num),0
);22 bool:=true;
23read(n,m);
24for i:=1
to2*n do
25for j:=1
to m do
26begin
27read(s[i,j]);
28if s[i,j]=0
then
inc(num[i]);
29end
;30 i:=1;31
while((num[i]=num[i+n])or(num[i]+num[i+n]=m))and(i<=n)do
32begin
33inc(i);
34if ((num[i]<>num[i+n])and(num[i]+num[i+n]<>m))and(i<=n)
35then bool:=false;
36end;37
ifnot bool then writeln('no'
)38else
39begin
40 h:=0;41
for i:=1
to n do
42if num[i]=m div
2then
begin inc(h); w[h]:=i; end;43
for i:=1
to n do
44begin
45if (num[i]<>num[i+n])and(num[i]+num[i+n]=m) then
46begin
47for j:=1
to m do
48if s[i,j]=0
then s[i,j]:=1
49else s[i,j]:=0;50
end;
51end
;52 bool2:=true;
53for i:=1
to m do
54 delete(num2[i],1
,length(num2[i]));
55for i:=1
to m do
56 delete(num3[i],1
,length(num3[i]));
57for j:=1
to m do
58for i:=1
to n do
59 num2[j]:=num2[j]+chr(s[i,j]+48
);60
for j:=1
to m do
61for i:=n+1
to2*n do
62 num3[j]:=num3[j]+chr(s[i,j]+48
);63 j:=0;64
fillchar(boo,sizeof(boo),true);
65 bool2:=true;
66repeat
67inc(j);
68 t:=0;69
repeat
70inc(t);
71if (num2[j]=num3[t])and(boo[t])then boo[t]:=false;
72until((num2[j]=num3[t]))or(t>=m);
73if (num2[j]<>num3[t])and(j<=m)
74then bool2:=false;
75until (num2[j]<>num3[t]) or (j>=m);
76if
not bool2 then
77begin
78 inc(jin[1
]);79 e:=1;80
while jin[e]=2
dobegin jin[e]:=0; inc(e); inc(jin[e]) end;81
if w[h+1]=1
then write('no'
)82else
begin
83for i:=1
to h do
84if w[h]=1
then
85begin
86end;87
end;
88else writeln('
yes'
);89
end;
90end;91
close(input);
92close(output);
93end.
記住教訓啊!
2012-10-09
A 搜尋演算法
啟發式搜尋演算法 要理解 a 搜尋演算法,還得從啟發式搜尋演算法開始談起。所謂啟發式搜尋,就在於當前搜尋結點往下選擇下一步結點時,可以通過乙個啟發函式 來進行選擇,選擇代價最少的結點作為下一步搜尋結點而跳轉其上 遇到有乙個以上代價最 少的結點,不妨選距離當前搜尋點最近一次展開的搜尋點進行下一步搜尋 ...
A 搜尋演算法
a 演算法是基於bfs的一種入門級啟發式搜尋演算法,就是將bfs的佇列改為基於估價的優先佇列,可以快速地找到答案。優先隊列為小根堆 while 優先佇列不為空 取出隊頭並擴充套件 將擴充套件節點以估價值 當前值為優先順序入隊 endwhile估價函式越接近真實值演算法越優,但一定不能大於真實值,否則...
搜尋演算法小結
搜尋演算法是利用計算機的高效能來有目的的窮舉乙個問題的部分和所有的可能情況,從而求出問題的解的一種方法。常用的搜尋演算法有 一.回溯法 回溯演算法是所有搜尋演算法中最為基本的一種演算法,其採用了一種 走不通就掉頭 思想作為其控制結構,其相當於採用了先根遍歷的方法來構造解答樹,可用於找解或所有解以及最...