AIX 程式設計大賽---AIX正方形問題
AIX 程式設計大賽---AIX正方形問題
作者:成曉旭
作為“演算法及實現”欄目的“拋磚引玉”之作,將自己2年多前實現的一個演算法放出來。有一年IBM出了這個Java程式設計競賽題,當時,自己花晚上時間用Java實現了。
[問題描述]:
任意給定一個正方形,將正方形的各邊做n等分,並將相應各點連線成水平或垂直的直線,如果從正方形的左下角(0,0)出發,沿各邊線或連線線,自左向右或自下而上的方向,到達正方形的右上角(n,n),請用JAVA程式計算並輸出所有可能的路徑總數和具體線路.請提供相關JAVA源程式和n=2,3,4時的輸出結果。輸出結果按以下方式:
以n=1為例:
n = 1
Path1: (0,0) - (0,1) - (1,1)
Path2: (0,0) - (1,0) - (1,1)
Total = 2
[設計簡介]:
共設計3個類:
AixPoint:正方形問題的低層處理類,抽象正方形問題的每個訪問點資訊;
AixSquare:正方形問題的核心處理類,抽象正方形演算法處理過程;
AixContest:正方形問題的客戶呼叫處理類,抽象正方形問題的應用層。
[演算法原始碼]:
AixPoint原始碼:
/** *//*******************************************************************************
* <>
* AIXContest ver1.0
* 開發作者: 成曉旭
* 專案簡述: AIX程式設計的Java程式設計"AIX正方形問題"解決方案
* 啟動時間: 2004年01月14日 20:00:08
* 完成時間: 2003年01月14日 20:09:00 <1個晚上>
*
* 開發環境: Windows2000 Professional + SUN J2SE1.4.2
* 開發工具: Rational Rose2002 Enterprise + JCreator2.5Pro
*
* 檔名稱: AixPoint.java
* 簡 介: 正方形問題的低層處理類,抽象正方形問題的每個訪問點資訊
*
* 備 注:
*
* 修改時間1:
*
***************************************************************************** */
package CXXSoft.Aix;
import java.awt.Point;
public class AixPoint extends Point
...{
private int moveUnit;
public boolean aheadExcess;
public boolean aboveExcess;
//類構造器
public AixPoint()
...{
aheadExcess = false;
aboveExcess = false;
moveUnit = 1;
}
//類構造器
public AixPoint(int x,int y)
...{
this();
this.x = x;
this.y = y;
}
//類構造器
public AixPoint(Point p)
...{
this();
this.x = p.x;
this.y = p.y;
}
//向左移動(前進)
public void goAhead()
...{
this.x += moveUnit;
}
//向左的反方向移動(後退)
public void goAheadReturn()
...{
this.x -= moveUnit;
}
//向上移動
public void goAbove()
...{
this.y += moveUnit;
}
//向上的反方向移動(後退)
public void goAboveReturn()
...{
this.y -= moveUnit;
}
//形成輸出串
public String toString()
...{
return "("+ x + "," + y +")";
}
}
* <
* AIXContest ver1.0
* 開發作者: 成曉旭
* 專案簡述: AIX程式設計的Java程式設計"AIX正方形問題"解決方案
* 啟動時間: 2004年01月14日 20:00:08
* 完成時間: 2003年01月14日 20:09:00 <1個晚上>
*
* 開發環境: Windows2000 Professional + SUN J2SE1.4.2
* 開發工具: Rational Rose2002 Enterprise + JCreator2.5Pro
*
* 檔名稱: AixPoint.java
* 簡 介: 正方形問題的低層處理類,抽象正方形問題的每個訪問點資訊
*
* 備 注:
*
* 修改時間1:
*
*****************************************************************************
package CXXSoft.Aix;
import java.awt.Point;
public class AixPoint extends Point
...{
private int moveUnit;
public boolean aheadExcess;
public boolean aboveExcess;
//類構造器
public AixPoint()
...{
aheadExcess = false;
aboveExcess = false;
moveUnit = 1;
}
//類構造器
public AixPoint(int x,int y)
...{
this();
this.x = x;
this.y = y;
}
//類構造器
public AixPoint(Point p)
...{
this();
this.x = p.x;
this.y = p.y;
}
//向左移動(前進)
public void goAhead()
...{
this.x += moveUnit;
}
//向左的反方向移動(後退)
public void goAheadReturn()
...{
this.x -= moveUnit;
}
//向上移動
public void goAbove()
...{
this.y += moveUnit;
}
//向上的反方向移動(後退)
public void goAboveReturn()
...{
this.y -= moveUnit;
}
//形成輸出串
public String toString()
...{
return "("+ x + "," + y +")";
}
}
AixSquare原始碼:
/** *//*******************************************************************************
* <>
* AIXContest ver1.0
* 開發作者: 成曉旭
* 專案簡述: AIX程式設計的Java程式設計"AIX正方形問題"解決方案
* 啟動時間: 2004年01月14日 20:28:00
* 完成時間: 2003年01月17日 00:16:00<4個晚上>
*
* 開發環境: Windows2000 Professional + SUN J2SE1.4.2
* 開發工具: Rational Rose2002 Enterprise + JCreator2.5Pro
*
* 檔名稱: AixSquare.java
* 簡 介: 正方形問題的核心處理類,抽象正方形演算法處理過程
*
* 備 注:
*
* 修改時間1:
*
* [問題描述]:
* 任意給定一個正方形,將正方形的各邊做n等分,並將相應各點連線成水平
* 或垂直的直線,如果從正方形的左下角(0,0)出發,沿各邊線或連線線,
* 自左向右或自下而上的方向,到達正方形的右上角(n,n),
* 請用JAVA程式計算並輸出所有可能的路徑總數和具體線路.
* 請提供相關JAVA源程式和n=2,3,4時的輸出結果。輸出結果按以下方式:
* 以n=1為例:
* n = 1
* Path1: (0,0) - (0,1) - (1,1)
* Path2: (0,0) - (1,0) - (1,1)
* Total = 2
*
* [解答思路]:
* 此問題的核心是一個"有向無環圖"的遍歷問題,
* 解答的思想就是一個"試探"與"回溯"演算法的抽象與實現.甚至比完整的
* "有向無環圖"的遍歷問題還要簡單.
*
* [建模提示]:
* 為了簡化問題的處理過程,強調解決問題的實質性思路,在建模過程中,
* 對遍歷過程中每步"前進"的步長進行了"固定步長為1"的假設,即對將被
* n等分的正方形的邊長,自動設定為n,以簡化演算法中對邊的計算處理.
*
* [演算法優化]:
* 目前設計的演算法有以下幾處有待優化:
* 1:此題是一般的"試探"與"回溯"演算法一個特例,所以有些處理過程是可以省略的
* (目前實現的是一個標準的"試探"與"回溯"演算法)
* 2:由於題目自身的特殊性,對某些處理過程可做簡化,以提高演算法的執行效率
* (如:對進棧,出棧的處理,對訪問佇列的處理,對在正方形邊上"前進"時的
* 回溯處理,對臨界條件,到達目標點條件的判斷等等)
* 3:問題的本身及解答此題的思路是很具一般性的,但目前分析,設計的類結構過於特殊化.
*
***************************************************************************** */
package CXXSoft.Aix;
import java.awt.Point;
import java.util.Stack;
import java.util.Vector;
import java.util.List;
import CXXSoft.Aix.AixPoint;
public class AixSquare
...{
//AIX正方形問題點遍歷時前進方向常量定義
private final static int MOVE_AHEAD = 1; //向左
private final static int MOVE_ABOVE = 2; //向上
//AIX正方形問題點遍歷時優先前進的方向常量定義
public final static int FIRST_MOVE_AHEAD = 101; //先從左至右,後從下向上
public final static int FIRST_MOVE_ABOVE = 102; //先從下向上,後從左至右
private int moveUnit; //當前演算法處理的單位長度
private int nPart; //矩形邊被等分的份數
private int firstMoveWay; //正方形問題線路優先前進方向
private int nAccess; //正確的通路總數
private Point startP;
private Point endP;
private String strPath;
private Vector visitedPoint; //遍歷過程中已經訪問過的點佇列(每找到一條通道後被清空,然後重新載入)
private Stack visitStack; //遍歷過程中的堆疊
private Vector rightAccess; //能到達目標點的正確通路佇列
//演算法訪問的當前點
private AixPoint p;
private void visitPoint()
...{
if(strPath == null || strPath == "")
strPath = "Path" + (nAccess + 1) +": " + p;
else
strPath += " - " + p;
}
//判斷是否向左前進越界
private boolean isAheadExcess()
...{
return (p.x > endP.x);
}
//判斷是否向上前進越界
private boolean isAboveExcess()
...{
return (p.y > endP.y);
}
//將當前輪的遍歷結果點組成的遍歷線路儲存於rightAccess中
private void saveArriveLine()
...{
String str = "",strAccess = "";
for(int i=0;i<visitedPoint.size();i++)
...{
AixPoint q = (AixPoint)visitedPoint.get(i);
str = (str == null || str == "") ? " Path" + (nAccess + 1) +": " : " - ";
strAccess += str + q;
}
rightAccess.add(strAccess);
}
//判斷是否前進到目標點
private boolean isArriveAim()
...{
boolean isOK = false;
isOK = ((p.x == endP.x) && (p.y == endP.y)
&&(p.aheadExcess && p.aboveExcess));
if(isOK)
...{
saveArriveLine();
nAccess++;
strPath = "";
}
return isOK;
}
//遍歷的當前點進棧
private void pushPoint()
...{
visitStack.push(p);
}
//遍歷的當前點退棧
private void popPoint()
...{
if(!visitStack.empty())
...{
p = (AixPoint)visitStack.pop();
}
}
//修改遍歷堆疊中,引數指定的點的越界標誌
private void setVisitStackExcess(AixPoint para,int flag)
...{
for(int i=0;i<visitStack.size();i++)
...{
AixPoint q = (AixPoint)visitStack.get(i);
if(para == q)
...{
switch(flag)
...{
case MOVE_AHEAD:
q.aheadExcess = true;
break;
case MOVE_ABOVE:
q.aboveExcess = true;
break;
}
}
}
}
//遍歷的當前點進入佇列
private void enterList()
...{
visitedPoint.add(p);
}
//遍歷的當前點退出佇列(將當前點在遍歷佇列中刪除)
private void exitList()
...{
visitedPoint.remove(p);
}
//修改遍歷的當前點佇列中,引數指定的點的越界標誌
private void setVisitedListExcess(AixPoint para,int flag)
...{
for(int i=0;i<visitedPoint.size();i++)
...{
AixPoint q = (AixPoint)visitedPoint.get(i);
if(para == q)
...{
switch(flag)
...{
case MOVE_AHEAD:
q.aheadExcess = true;
break;
case MOVE_ABOVE:
q.aboveExcess = true;
break;
}
}
}
}
//判斷當前點是否已經在曾經訪問過的佇列中
private boolean isVisited()
...{
boolean isExist = false;
for(int i=0;i<visitedPoint.size();i++)
...{
if(p == (AixPoint)visitedPoint.get(i))
...{
isExist = true;
break;
}
}
return isExist;
}
//AIX正方形問題的"嘗試前進"方法
private void attempt(int flag)
...{
AixPoint q = new AixPoint(p);
p = q;
switch(flag)
...{
case MOVE_AHEAD:
//向左移動
p.goAhead(); //[向前嘗試]
break;
case MOVE_ABOVE:
//向上移動
p.goAbove(); //[向上嘗試]
}
}
//AIX正方形問題的"回溯後退"方法
private void backdate(int flag)
...{
popPoint(); //[向後/向下回溯]
pushPoint();
setVisitedListExcess(p,flag);
setVisitStackExcess(p,flag);
}
//新版:goAlwaysLeft()方法
protected void goAlwaysLeftNew()
...{
if(!isVisited())
...{
pushPoint();
enterList();
visitPoint();
}
attempt(MOVE_AHEAD);
if(isAheadExcess())
backdate(MOVE_AHEAD);
}
//新版:goAlwaysUpper()方法
protected void goAlwaysUpperNew()
...{
if(!isVisited())
...{
pushPoint();
enterList();
visitPoint();
}
attempt(MOVE_ABOVE);
if(isAboveExcess())
backdate(MOVE_ABOVE);
}
//成功找到一條通道後,回退到下一個正確的新起點方法
private void backdateNewStartPoint()
...{
while((p.aheadExcess && p.aboveExcess))
...{
if(p.x == startP.x && p.y == startP.y)
break;
popPoint();
if((p.x == endP.x) && (p.y == endP.y))
continue;
if(p.aheadExcess && !p.aboveExcess)
p.aboveExcess = true;
if(!p.aheadExcess && p.aboveExcess)
p.aheadExcess = true;
if((!p.aheadExcess && !p.aboveExcess))
...{
if((firstMoveWay == FIRST_MOVE_AHEAD) && (p.x <= startP.x))
...{
p.aheadExcess = true;
if(p.y >= endP.y)
p.aboveExcess = true;
}
if((firstMoveWay == FIRST_MOVE_ABOVE) && (p.y <= endP.y))
...{
p.aboveExcess = true;
if(p.x >= endP.x)
p.aheadExcess = true;
}
}
}
switch(firstMoveWay)
...{
case FIRST_MOVE_AHEAD:
p.aheadExcess = true;
break;
case FIRST_MOVE_ABOVE:
p.aboveExcess = true;
break;
}
pushPoint();
}
//成功找到一條通道後,從正確的新起點開始,將堆疊中所有的點轉存入遍歷佇列
private void TransStackToNewList()
...{
visitedPoint.clear();
for(int i = 0; i < visitStack.size();i++)
visitedPoint.add(visitStack.get(i));
}
//正方形問題的沿當前線路前進的核心演算法
private boolean advanceMoveKernel()
...{
switch(firstMoveWay)
...{
case FIRST_MOVE_AHEAD:
if(p.aheadExcess)
goAlwaysLeftNew();
else
goAlwaysUpperNew();
break;
case FIRST_MOVE_ABOVE:
if(p.aboveExcess)
goAlwaysUpperNew();
else
goAlwaysLeftNew();
break;
}
return isArriveAim();
}
//類構造器
public AixSquare()
...{
visitStack = new Stack();
visitedPoint = new Vector();
rightAccess = new Vector();
startP = new Point();
endP = new Point();
moveUnit = 1;
nAccess = 0;
strPath = "";
}
//類構造器
public void setProblemCondition(int part,int firstMove)
...{
this.firstMoveWay = firstMove;
if(part <= 0)
part = 1;
this.nPart = part;
endP.x = nPart;
endP.y = nPart;
nAccess = 0;
strPath = "";
visitStack.clear();
visitedPoint.clear();
rightAccess.clear();
}
//新版:正方形問題解答方法
public void solveProblemNew()
...{
boolean arriveAim = false;
p = new AixPoint(startP);
while(!p.aheadExcess || !p.aboveExcess)
...{
while(!p.aheadExcess || !p.aboveExcess)
...{
switch(firstMoveWay)
...{
case FIRST_MOVE_AHEAD:
if(!p.aheadExcess)
goAlwaysLeftNew();
else
goAlwaysUpperNew();
break;
case FIRST_MOVE_ABOVE:
if(!p.aboveExcess)
goAlwaysUpperNew();
else
goAlwaysLeftNew();
break;
}
arriveAim = isArriveAim();
if(arriveAim)
break;
}
backdateNewStartPoint();
TransStackToNewList();
if(visitStack.isEmpty() && (p.x == startP.x && p.y == startP.y))
break;
}
}
//類的處理結果輸出串
public String toString()
...{
String str=" n = " + nPart;
for(int i=0;i<rightAccess.size();i++)
...{
str += rightAccess.get(i);
}
str += " Total = " + nAccess;
return str;
}
}
* <
* AIXContest ver1.0
* 開發作者: 成曉旭
* 專案簡述: AIX程式設計的Java程式設計"AIX正方形問題"解決方案
* 啟動時間: 2004年01月14日 20:28:00
* 完成時間: 2003年01月17日 00:16:00<4個晚上>
*
* 開發環境: Windows2000 Professional + SUN J2SE1.4.2
* 開發工具: Rational Rose2002 Enterprise + JCreator2.5Pro
*
* 檔名稱: AixSquare.java
* 簡 介: 正方形問題的核心處理類,抽象正方形演算法處理過程
*
* 備 注:
*
* 修改時間1:
*
* [問題描述]:
* 任意給定一個正方形,將正方形的各邊做n等分,並將相應各點連線成水平
* 或垂直的直線,如果從正方形的左下角(0,0)出發,沿各邊線或連線線,
* 自左向右或自下而上的方向,到達正方形的右上角(n,n),
* 請用JAVA程式計算並輸出所有可能的路徑總數和具體線路.
* 請提供相關JAVA源程式和n=2,3,4時的輸出結果。輸出結果按以下方式:
* 以n=1為例:
* n = 1
* Path1: (0,0) - (0,1) - (1,1)
* Path2: (0,0) - (1,0) - (1,1)
* Total = 2
*
* [解答思路]:
* 此問題的核心是一個"有向無環圖"的遍歷問題,
* 解答的思想就是一個"試探"與"回溯"演算法的抽象與實現.甚至比完整的
* "有向無環圖"的遍歷問題還要簡單.
*
* [建模提示]:
* 為了簡化問題的處理過程,強調解決問題的實質性思路,在建模過程中,
* 對遍歷過程中每步"前進"的步長進行了"固定步長為1"的假設,即對將被
* n等分的正方形的邊長,自動設定為n,以簡化演算法中對邊的計算處理.
*
* [演算法優化]:
* 目前設計的演算法有以下幾處有待優化:
* 1:此題是一般的"試探"與"回溯"演算法一個特例,所以有些處理過程是可以省略的
* (目前實現的是一個標準的"試探"與"回溯"演算法)
* 2:由於題目自身的特殊性,對某些處理過程可做簡化,以提高演算法的執行效率
* (如:對進棧,出棧的處理,對訪問佇列的處理,對在正方形邊上"前進"時的
* 回溯處理,對臨界條件,到達目標點條件的判斷等等)
* 3:問題的本身及解答此題的思路是很具一般性的,但目前分析,設計的類結構過於特殊化.
*
*****************************************************************************
package CXXSoft.Aix;
import java.awt.Point;
import java.util.Stack;
import java.util.Vector;
import java.util.List;
import CXXSoft.Aix.AixPoint;
public class AixSquare
...{
//AIX正方形問題點遍歷時前進方向常量定義
private final static int MOVE_AHEAD = 1; //向左
private final static int MOVE_ABOVE = 2; //向上
//AIX正方形問題點遍歷時優先前進的方向常量定義
public final static int FIRST_MOVE_AHEAD = 101; //先從左至右,後從下向上
public final static int FIRST_MOVE_ABOVE = 102; //先從下向上,後從左至右
private int moveUnit; //當前演算法處理的單位長度
private int nPart; //矩形邊被等分的份數
private int firstMoveWay; //正方形問題線路優先前進方向
private int nAccess; //正確的通路總數
private Point startP;
private Point endP;
private String strPath;
private Vector visitedPoint; //遍歷過程中已經訪問過的點佇列(每找到一條通道後被清空,然後重新載入)
private Stack visitStack; //遍歷過程中的堆疊
private Vector rightAccess; //能到達目標點的正確通路佇列
//演算法訪問的當前點
private AixPoint p;
private void visitPoint()
...{
if(strPath == null || strPath == "")
strPath = "Path" + (nAccess + 1) +": " + p;
else
strPath += " - " + p;
}
//判斷是否向左前進越界
private boolean isAheadExcess()
...{
return (p.x > endP.x);
}
//判斷是否向上前進越界
private boolean isAboveExcess()
...{
return (p.y > endP.y);
}
//將當前輪的遍歷結果點組成的遍歷線路儲存於rightAccess中
private void saveArriveLine()
...{
String str = "",strAccess = "";
for(int i=0;i<visitedPoint.size();i++)
...{
AixPoint q = (AixPoint)visitedPoint.get(i);
str = (str == null || str == "") ? " Path" + (nAccess + 1) +": " : " - ";
strAccess += str + q;
}
rightAccess.add(strAccess);
}
//判斷是否前進到目標點
private boolean isArriveAim()
...{
boolean isOK = false;
isOK = ((p.x == endP.x) && (p.y == endP.y)
&&(p.aheadExcess && p.aboveExcess));
if(isOK)
...{
saveArriveLine();
nAccess++;
strPath = "";
}
return isOK;
}
//遍歷的當前點進棧
private void pushPoint()
...{
visitStack.push(p);
}
//遍歷的當前點退棧
private void popPoint()
...{
if(!visitStack.empty())
...{
p = (AixPoint)visitStack.pop();
}
}
//修改遍歷堆疊中,引數指定的點的越界標誌
private void setVisitStackExcess(AixPoint para,int flag)
...{
for(int i=0;i<visitStack.size();i++)
...{
AixPoint q = (AixPoint)visitStack.get(i);
if(para == q)
...{
switch(flag)
...{
case MOVE_AHEAD:
q.aheadExcess = true;
break;
case MOVE_ABOVE:
q.aboveExcess = true;
break;
}
}
}
}
//遍歷的當前點進入佇列
private void enterList()
...{
visitedPoint.add(p);
}
//遍歷的當前點退出佇列(將當前點在遍歷佇列中刪除)
private void exitList()
...{
visitedPoint.remove(p);
}
//修改遍歷的當前點佇列中,引數指定的點的越界標誌
private void setVisitedListExcess(AixPoint para,int flag)
...{
for(int i=0;i<visitedPoint.size();i++)
...{
AixPoint q = (AixPoint)visitedPoint.get(i);
if(para == q)
...{
switch(flag)
...{
case MOVE_AHEAD:
q.aheadExcess = true;
break;
case MOVE_ABOVE:
q.aboveExcess = true;
break;
}
}
}
}
//判斷當前點是否已經在曾經訪問過的佇列中
private boolean isVisited()
...{
boolean isExist = false;
for(int i=0;i<visitedPoint.size();i++)
...{
if(p == (AixPoint)visitedPoint.get(i))
...{
isExist = true;
break;
}
}
return isExist;
}
//AIX正方形問題的"嘗試前進"方法
private void attempt(int flag)
...{
AixPoint q = new AixPoint(p);
p = q;
switch(flag)
...{
case MOVE_AHEAD:
//向左移動
p.goAhead(); //[向前嘗試]
break;
case MOVE_ABOVE:
//向上移動
p.goAbove(); //[向上嘗試]
}
}
//AIX正方形問題的"回溯後退"方法
private void backdate(int flag)
...{
popPoint(); //[向後/向下回溯]
pushPoint();
setVisitedListExcess(p,flag);
setVisitStackExcess(p,flag);
}
//新版:goAlwaysLeft()方法
protected void goAlwaysLeftNew()
...{
if(!isVisited())
...{
pushPoint();
enterList();
visitPoint();
}
attempt(MOVE_AHEAD);
if(isAheadExcess())
backdate(MOVE_AHEAD);
}
//新版:goAlwaysUpper()方法
protected void goAlwaysUpperNew()
...{
if(!isVisited())
...{
pushPoint();
enterList();
visitPoint();
}
attempt(MOVE_ABOVE);
if(isAboveExcess())
backdate(MOVE_ABOVE);
}
//成功找到一條通道後,回退到下一個正確的新起點方法
private void backdateNewStartPoint()
...{
while((p.aheadExcess && p.aboveExcess))
...{
if(p.x == startP.x && p.y == startP.y)
break;
popPoint();
if((p.x == endP.x) && (p.y == endP.y))
continue;
if(p.aheadExcess && !p.aboveExcess)
p.aboveExcess = true;
if(!p.aheadExcess && p.aboveExcess)
p.aheadExcess = true;
if((!p.aheadExcess && !p.aboveExcess))
...{
if((firstMoveWay == FIRST_MOVE_AHEAD) && (p.x <= startP.x))
...{
p.aheadExcess = true;
if(p.y >= endP.y)
p.aboveExcess = true;
}
if((firstMoveWay == FIRST_MOVE_ABOVE) && (p.y <= endP.y))
...{
p.aboveExcess = true;
if(p.x >= endP.x)
p.aheadExcess = true;
}
}
}
switch(firstMoveWay)
...{
case FIRST_MOVE_AHEAD:
p.aheadExcess = true;
break;
case FIRST_MOVE_ABOVE:
p.aboveExcess = true;
break;
}
pushPoint();
}
//成功找到一條通道後,從正確的新起點開始,將堆疊中所有的點轉存入遍歷佇列
private void TransStackToNewList()
...{
visitedPoint.clear();
for(int i = 0; i < visitStack.size();i++)
visitedPoint.add(visitStack.get(i));
}
//正方形問題的沿當前線路前進的核心演算法
private boolean advanceMoveKernel()
...{
switch(firstMoveWay)
...{
case FIRST_MOVE_AHEAD:
if(p.aheadExcess)
goAlwaysLeftNew();
else
goAlwaysUpperNew();
break;
case FIRST_MOVE_ABOVE:
if(p.aboveExcess)
goAlwaysUpperNew();
else
goAlwaysLeftNew();
break;
}
return isArriveAim();
}
//類構造器
public AixSquare()
...{
visitStack = new Stack();
visitedPoint = new Vector();
rightAccess = new Vector();
startP = new Point();
endP = new Point();
moveUnit = 1;
nAccess = 0;
strPath = "";
}
//類構造器
public void setProblemCondition(int part,int firstMove)
...{
this.firstMoveWay = firstMove;
if(part <= 0)
part = 1;
this.nPart = part;
endP.x = nPart;
endP.y = nPart;
nAccess = 0;
strPath = "";
visitStack.clear();
visitedPoint.clear();
rightAccess.clear();
}
//新版:正方形問題解答方法
public void solveProblemNew()
...{
boolean arriveAim = false;
p = new AixPoint(startP);
while(!p.aheadExcess || !p.aboveExcess)
...{
while(!p.aheadExcess || !p.aboveExcess)
...{
switch(firstMoveWay)
...{
case FIRST_MOVE_AHEAD:
if(!p.aheadExcess)
goAlwaysLeftNew();
else
goAlwaysUpperNew();
break;
case FIRST_MOVE_ABOVE:
if(!p.aboveExcess)
goAlwaysUpperNew();
else
goAlwaysLeftNew();
break;
}
arriveAim = isArriveAim();
if(arriveAim)
break;
}
backdateNewStartPoint();
TransStackToNewList();
if(visitStack.isEmpty() && (p.x == startP.x && p.y == startP.y))
break;
}
}
//類的處理結果輸出串
public String toString()
...{
String str=" n = " + nPart;
for(int i=0;i<rightAccess.size();i++)
...{
str += rightAccess.get(i);
}
str += " Total = " + nAccess;
return str;
}
}
AixContest原始碼:
/** *//*******************************************************************************
* <>
* AIXContest ver1.0
* 開發作者: 成曉旭
* 專案簡述: AIX程式設計的Java程式設計"AIX正方形問題"解決方案
* 啟動時間: 2004年01月14日 20:00:00
* 完成時間: 2003年01月14日 23:16:00<3個晚上>
*
* 開發環境: Windows2000 Professional + SUN J2SE1.4.2
* 開發工具: Rational Rose2002 Enterprise + JCreator2.5Pro
*
* 檔名稱: AixContest.java
* 簡 介: 正方形問題的客戶呼叫處理類,抽象正方形問題的應用層
*
* 備 注:
*
* 修改時間1:
*
* [問題描述]:
* 任意給定一個正方形,將正方形的各邊做n等分,並將相應各點連線成水平
* 或垂直的直線,如果從正方形的左下角(0,0)出發,沿各邊線或連線線,
* 自左向右或自下而上的方向,到達正方形的右上角(n,n),
* 請用JAVA程式計算並輸出所有可能的路徑總數和具體線路.
* 請提供相關JAVA源程式和n=2,3,4時的輸出結果。輸出結果按以下方式:
* 以n=1為例:
* n = 1
* Path1: (0,0) - (0,1) - (1,1)
* Path2: (0,0) - (1,0) - (1,1)
* Total = 2
*
* [解答思路]:
* 此問題的核心是一個"有向無環圖"的遍歷問題,
* 解答的思想就是一個"試探"與"回溯"演算法的抽象與實現.甚至比完整的
* "有向無環圖"的遍歷問題還要簡單.
*
* [建模提示]:
* 為了簡化問題的處理過程,強調解決問題的實質性思路,在建模過程中,
* 對遍歷過程中每步"前進"的步長進行了"固定步長為1"的假設,即對將被
* n等分的正方形的邊長,自動設定為n,以簡化演算法中對邊的計算處理.
*
* [演算法優化]:
* 目前設計的演算法有以下幾處有待優化:
* 1:此題是一般的"試探"與"回溯"演算法一個特例,所以有些處理過程是可以省略的
* (目前實現的是一個標準的"試探"與"回溯"演算法)
* 2:由於題目自身的特殊性,對某些處理過程可做簡化,以提高演算法的執行效率
* (如:對進棧,出棧的處理,對訪問佇列的處理,對在正方形邊上"前進"時的
* 回溯處理,對臨界條件,到達目標點條件的判斷等等)
* 3:問題的本身及解答此題的思路是很具一般性的,但目前分析,設計的類結構過於特殊化.
***************************************************************************** */
package CXXSoft.Aix;
import java.awt.Point;
import CXXSoft.Aix.AixSquare;
public class AixContest
...{
public static void main(String[] arg)
...{
System.out.println("AIX知識大賽初賽Java程式設計---AIX正方形問題");
AixSquare asProblem = new AixSquare();
String str="";
for(int i=1;i<=3;i++)
...{
asProblem.setProblemCondition(i,AixSquare.FIRST_MOVE_AHEAD);
asProblem.solveProblemNew();
str += asProblem + " ";
}
System.out.println(str);
System.out.println(" AIX正方形問題---執行結束......");
}
}
* <
* AIXContest ver1.0
* 開發作者: 成曉旭
* 專案簡述: AIX程式設計的Java程式設計"AIX正方形問題"解決方案
* 啟動時間: 2004年01月14日 20:00:00
* 完成時間: 2003年01月14日 23:16:00<3個晚上>
*
* 開發環境: Windows2000 Professional + SUN J2SE1.4.2
* 開發工具: Rational Rose2002 Enterprise + JCreator2.5Pro
*
* 檔名稱: AixContest.java
* 簡 介: 正方形問題的客戶呼叫處理類,抽象正方形問題的應用層
*
* 備 注:
*
* 修改時間1:
*
* [問題描述]:
* 任意給定一個正方形,將正方形的各邊做n等分,並將相應各點連線成水平
* 或垂直的直線,如果從正方形的左下角(0,0)出發,沿各邊線或連線線,
* 自左向右或自下而上的方向,到達正方形的右上角(n,n),
* 請用JAVA程式計算並輸出所有可能的路徑總數和具體線路.
* 請提供相關JAVA源程式和n=2,3,4時的輸出結果。輸出結果按以下方式:
* 以n=1為例:
* n = 1
* Path1: (0,0) - (0,1) - (1,1)
* Path2: (0,0) - (1,0) - (1,1)
* Total = 2
*
* [解答思路]:
* 此問題的核心是一個"有向無環圖"的遍歷問題,
* 解答的思想就是一個"試探"與"回溯"演算法的抽象與實現.甚至比完整的
* "有向無環圖"的遍歷問題還要簡單.
*
* [建模提示]:
* 為了簡化問題的處理過程,強調解決問題的實質性思路,在建模過程中,
* 對遍歷過程中每步"前進"的步長進行了"固定步長為1"的假設,即對將被
* n等分的正方形的邊長,自動設定為n,以簡化演算法中對邊的計算處理.
*
* [演算法優化]:
* 目前設計的演算法有以下幾處有待優化:
* 1:此題是一般的"試探"與"回溯"演算法一個特例,所以有些處理過程是可以省略的
* (目前實現的是一個標準的"試探"與"回溯"演算法)
* 2:由於題目自身的特殊性,對某些處理過程可做簡化,以提高演算法的執行效率
* (如:對進棧,出棧的處理,對訪問佇列的處理,對在正方形邊上"前進"時的
* 回溯處理,對臨界條件,到達目標點條件的判斷等等)
* 3:問題的本身及解答此題的思路是很具一般性的,但目前分析,設計的類結構過於特殊化.
*****************************************************************************
package CXXSoft.Aix;
import java.awt.Point;
import CXXSoft.Aix.AixSquare;
public class AixContest
...{
public static void main(String[] arg)
...{
System.out.println("AIX知識大賽初賽Java程式設計---AIX正方形問題");
AixSquare asProblem = new AixSquare();
String str="";
for(int i=1;i<=3;i++)
...{
asProblem.setProblemCondition(i,AixSquare.FIRST_MOVE_AHEAD);
asProblem.solveProblemNew();
str += asProblem + " ";
}
System.out.println(str);
System.out.println(" AIX正方形問題---執行結束......");
}
}
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1108610
相關文章
- AIX OOM問題AIOOM
- aix bosboot問題AIboot
- 【AIX】AIX中級試題AI
- AIX問題解決思路AI
- 【AIX】AIX程式監控工具AI
- AIX常見問題整理(二)AI
- AIX試題AI
- AIX發現EMC LUN的問題AI
- aix 6.1 ORA-04030 問題AI
- aix 共享記憶體段問題AI記憶體
- aix的程式AI
- 程式設計大賽WBS程式設計
- VNC FOR AIX 灰屏的問題解決VNCAI
- aix 遠端登陸緩慢問題AI
- AIX maxperm引數導致監聽問題AI
- AIX安裝oracle遇到的問題彙總AIOracle
- aix下jvm引數最佳化問題AIJVM
- AIX檔案系統滿的問題分析AI
- AIX 上VMO設定不當造成的資源不足的“問題”AI
- 解決AIX忘記root密碼的問題AI密碼
- aix5.3+weblogic814問題解決AIWeb
- CU--Shell程式設計大賽程式設計
- 幽默:程式設計師吹牛大賽程式設計師
- 【程式設計大賽刷題記錄】C語言 06程式設計C語言
- 【程式設計大賽刷題記錄】C語言 02程式設計C語言
- aixAI
- 【AIX】AIX記憶體機制AI記憶體
- AIX下NFS共享設定AINFS
- aix6安裝oracle 10g rac問題AIOracle 10g
- AIX網路一會通一會不通的問題AI
- AIX 上建立裸裝置lv出現的問題AI
- aix系統topas命令疑問AI
- 正方形計數 題解
- 【AIX】AIX 下磁碟 I/O 效能分析AI
- AIX程式記憶體佔用數的計算AI記憶體
- AIX VGDAAI
- AIX NFSAINFS
- aix 雜AI