国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

跳馬問題中存在的多種算法思想

2012-04-29 00:44:03鄧立波
中國信息技術教育 2012年1期
關鍵詞:數(shù)組棋盤起點

鄧立波

在信息量飛速增長的現(xiàn)代社會中,如何有效地獲取和處理信息已成了信息技術教師面對的課題之一。如何有條理地分析各種問題中的有用數(shù)據(jù),發(fā)現(xiàn)數(shù)據(jù)的變化規(guī)律,制訂相應的處理方法,構建解決整個問題的流程,也成了教師們的日常工作之一。眾所周知,計算機的特征是運算速度快、精度高,在精確的控制之下,一切都會按部就班地執(zhí)行,從而提高效率。如果我們能很好地利用計算機這個工具,那么我們就只需做個規(guī)劃者,而繁瑣的處理過程就可以留給計算機來執(zhí)行。下面我就以對一個問題的分析來說明流程控制中的多樣性。

問題描述:

設一個m*n的棋盤,在棋盤上左下角的A點(0,0)有一個中國象棋的馬,并約定馬走的規(guī)則是:①馬走日字;②馬只能向右走。任務:編程讀入m,n,請打印出一條從A(0,0)到B(m,n)的路徑。

跳馬問題也稱為騎士遍歷問題,是一道非常古老的題目了,好多人在講回溯算法時都喜歡用到這個例子,因為這是適合用回溯法解決的一個經典例子,它僅用一張平面表格就把階段、狀態(tài)、決策等因素直觀而又抽象地展現(xiàn)在人們面前。但我們不希望僅以一道或幾道經典題目,讓學生掌握一種算法,而是從不同的角度、方向來分析當前這種變化規(guī)則,找到適合的方法來處理目前這種變化,從而提高學生的解題適應能力。

● 回溯法適用于解決多階段決策問題中求單路徑、全路徑等

用回溯法解決跳馬問題的基本思想是從起點開始每一步先作出選擇,再判斷,再跨出到下一步,重復上述過程,每一步的跨出都會離目的地越來越近,但當?shù)讲涣四康牡貢r,回退一步,如果可以作出新的選擇,則重新跨出,否則再退,以此類推。上述過程可以借助于圖形進行模擬,讓學生先清楚整個過程。接下來便是每一步驟的語言描述及控制。其中每一步所做出的選擇必須記錄,否則回退時不能做出新的選擇。

求單路徑的流程圖如下:

參考程序:

program knight1;

const dx:array[1..4] of integer=(1,2,2,1);

dy:array[1..4] of integer=(-2,-1,1,2);

max=1000;

var x,y,m,k,i,mm,nn:integer;

b:array[0..max] of integer;

begin

write('input m,n:');

readln(mm,nn);

x:=0;y:=0;

m:=0;

k:=0;

for i:=0 to max do b[i]:=0;

while (x<>mm) or (y<>nn) do{目標點為(mm,nn)}

begin

k:=k+1; {找個方向}

if k>4 then begin k:=b[m]; {沒有方向可跳,則回溯}

m:=m-1;

x:=x-dx[k];

y:=y-dy[k];

end

else

if (x+dx[k]<=mm) or (y+dy[k]>=0) or (y+dy[k]<=nn) then

begin {繼續(xù)往下跳}

m:=m+1;

b[m]:=k;

k:=0;

end;

end;

for i:=1 to m do write(b[i]:9);{輸出每步的方向}

writeln;

x:=0;y:=0; {輸出路徑}

write('(0,0)--->');

for i:=1 to m do

begin

x:=x+dx[b[i]];

y:=y+dy[b[i]];

if i<>m then write('(',x,',',y,')','--->')

else writeln('(',x,',',y,')');

end;

readln;

end.

以上是求從起點到終點的一條路徑,這是一種能深入先深入,否則回退,換條路走的思維方式,即深度優(yōu)先搜索。但能否把所有路徑都打印出來呢?引導學生繼續(xù)思考。也就是一條路徑找到后,不能結束,要繼續(xù)找下一條路徑,因此結束條件要更改。觀察B數(shù)組的變化規(guī)則,只能當所有路徑找全后,也就是數(shù)組B的每一位都為最大值,才能讓程序結束,這是一種記數(shù)現(xiàn)象,但要判斷每一位是否達到最大值較繁瑣,我們再加一,也就是第一位的前一位發(fā)生變化,因此采用0位做標記位,初始化為0,當為1時結束。但調試程序后發(fā)現(xiàn)有201錯誤,也就是數(shù)組超界情況。仔細觀察發(fā)現(xiàn)當回退到B數(shù)組的0位時,K的值為0,也就是會發(fā)生dx[0],dy[0]的現(xiàn)象,根據(jù)現(xiàn)象采用兩種不同的控制方式:①加判斷語句,當K為0時不做x:=x-dx[k],y:=y-dy[k];②當K為0時,用BREAK結束程序。

● 用遞歸思想解決問題

在用回溯法分析這個問題之后,學生對跳馬問題的解題思路已經有了一定的了解,那我們還可以讓學生用遞歸的思想來分析這個問題。也就是從問題的規(guī)模出發(fā),不同規(guī)模的問題解決方案是否一致,能否找到大規(guī)模問題與小規(guī)模問題(子問題)間的關系,并建立遞歸模型。本題在每一步上存在四種選擇,如果選擇合適(不超界),則離終點近了一步,問題規(guī)模變小,但解決子問題的方法與原問題一致。

參考程序:

program ex(input,output);

const dx:array [1..4] of integer=(1,2,2,1);

dy:array [1..4] of integer=(-2,-1,1,2);

var

m,n,c:integer;

procedure cs(x,y:integer);

var

i:integer;

begin

if (x=m) and (y=n) then c:=c+1

else for i:=1 to 4 do

if (x+dx[i]<=m) and (y+dy[i]<=n) and (y+dy[i]>=0) then

cs(x+dx[i],y+dy[i]);

end;

begin

c:=0;

read(m,n);

cs(0,0);

writeln(c);

end.

以上是從起點出發(fā)編寫的遞歸程序。如何從終點開始尋找遞歸關系、編寫程序,大家可自行嘗試。

而如果要求到終點的所有路徑是多少,是否一定要用上述方法求出所有路徑,然后統(tǒng)計呢?仔細觀察,可以發(fā)現(xiàn)本問題步驟性強,馬跳的方向很明顯,前后結果有著必然的聯(lián)系。用遞歸思想很容易找到總數(shù)量與子問題之間的關系,即如果能把到達終點前各點的方案數(shù)計算清楚,則終點的方案數(shù)為馬從終點回退一步能到的點的方案數(shù)之和。得出遞歸關系式:

邊界條件為f(1,1)=1

注意:m為寬,n為高,它們的值不能超出棋盤范圍,可把第一列初始化為0,然后采用記憶方式求解。

找到遞歸關系,用遞推很容易地求出了起點到終點的總方案數(shù)。那么在此基礎上能否找到起點到終點的路徑呢?可再引導學生思考。此時如果從終點回退,而回退到的點有具體數(shù)值,也就是說,馬能從起點跳到剛才那一點,記載那一點的坐標。以此類推,把馬從終點退到起點的坐標都記載下來,就形成了一條通路。從這里可以看到,遞推也可以用到尋找路徑。

根據(jù)一個問題的本質進行多方面、多角度思考,一方面可以更加清晰地認識到問題的本質,另一方面也可以鍛煉思維能力。一題多解,從多種方案中總結出較好的方法,這種思維方式,不管是對問題的全局還是局部,都可以提高對問題的理解和解決,從而方便對過程的控制。

猜你喜歡
數(shù)組棋盤起點
JAVA稀疏矩陣算法
電腦報(2022年13期)2022-04-12 00:32:38
JAVA玩轉數(shù)學之二維數(shù)組排序
電腦報(2020年24期)2020-07-15 06:12:41
弄清楚“起點”前面有多少
起點
我的“新”起點
棋盤人生
尋找勾股數(shù)組的歷程
新年的起點
棋盤里的天文數(shù)字
棋盤疑案
乐亭县| 普安县| 武清区| 英超| 合阳县| 定南县| 永和县| 丹江口市| 公主岭市| 南丹县| 手机| 临汾市| 平舆县| 贡觉县| 成武县| 晋宁县| 五寨县| 汽车| 宝清县| 肇源县| 林甸县| 桓仁| 镇沅| 绵竹市| 定远县| 巍山| 德江县| 奉新县| 长治市| 古交市| 宁强县| 太湖县| 营山县| 南宫市| 枝江市| 林芝县| 塘沽区| 太湖县| 武平县| 北票市| 金坛市|