AIX 程序设计大赛-AIX正方形问题算法及Java程序实现(方案三)

 
这是到目前为止,我觉得这是最简单的实现《AIX 程序设计大赛- AIX 正方形问题》的解决方案。
 
问题描述:
任意给定一个正方形,将正方形的各边做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
 
解决思路:
由题目要求,“沿各边线或连接线,自左向右或自下而上的方向,到达正方形的右上角”,可以得出一条完整的有效的路径,即是向上走n步,向右走n步的排列组合,即可得到所有路径的条数等于:
所有路径条数=(2n)!/(n!*n!)
 
我们把向上走一步用 1 表示,向右走一步用 0 表示,那么一条完整的有效路径就可以表示成n个 1和n个0组成的字符串,若n=3,那么“111000”就表示向上走到(0,3),再水平走到(3,3);“110100”就表示(0,0)-(0,1)-(0,2)-(1,2)-(1,3)-(2,3)-(3,3)。
所以所有的路径,就可以通过遍历从二进制“0...01...1”到“1...10...0”之间的所有数,只要其二进制表示中含有n个1,就是一条有效的路径。
 
算法特点:
本算法将几何问题,抽象成排列组合问题,因此实现算法理解性非常好,程序实现也非常简单,只是和前面两篇文章中的算法相比,对于每一0~11…100…0(二进制数)之间的数都要判断,所以性能上相对差一些。
 
程序设计:
这个算法的程序实现非常简单,在这里用两个类来实现,一个命名为AixUtil3,表示用到的各种方法,另一个命名AixClient3,通过调用AixUtil3遍历正方形的各条路径并打印。
 
Java程序源代码: 
AixUtil3:处理类,按照向上优先策略,提供解决AIX正方形问题的一些静态方法
 
package  qinysong.aix;

/**
 * <p>Title: 方案3,通过抽象成排列组合进行实现</p>
 * <p>Description: AIX 程序设计大赛---AIX正方形问题</p>
 * <p>Copyright: Copyright (c) 2006</p>
 * <p>Company: qinysong</p>
 * 
@author  zhaoqingsong
 * 
@version  1.0
 
*/

public   class  AixUtil3 {

  
private   static   int  nValue;
  
private   static   int  minValue;
  
private   static   int  maxValue;
  
private   static   int [] binaryArray;
  
  
/**
   * 初始化正方形边长
   * 
@param  nValue int
   
*/
  
public   static   void  initNValue( int  nValue){
    
if  (nValue  <=   0 ) {
      
throw   new  RuntimeException( " 初始化正方形边长异常,长度不能小于等于零 " );
    }
    AixUtil3.nValue 
=  nValue;
    binaryArray 
=   new   int [ 2 * nValue];
    String binaryString1 
=   "" ;
    String binaryString0 
=   "" ;
    
for  ( int  i  =   0 ; i  <  nValue; i ++ ){
      binaryString1 
+=   " 1 " ;
      binaryString0 
+=   " 0 " ;
    }
    minValue 
=  Integer.parseInt(binaryString0 + binaryString1,  2 );
    maxValue 
=  Integer.parseInt(binaryString1 + binaryString0,  2 );
  }
  
  
/**
   * 取得路径值为pathValue,二进制字符串中1的个数
   * 并将二进制字符串进行缓存,以便取得该值所对应的路径
   * 
@param  pathValue int  路径值
   * 
@return  int  二进制字符串中1的个数
   
*/
  
public   static   int  getOneBitCount( int  pathValue){
    
int  index  =   0 ;
    
int  oneBitCount  =   0 ;
    
int  modules  =   0 ;
    
int  tempValue  =  pathValue;
    
while  ( tempValue  >   0  ){
      modules 
=  tempValue % 2 ;
      oneBitCount 
+=  modules;
      binaryArray[index
++ =  modules;
      tempValue 
=  tempValue / 2 ;
    }
    
return  oneBitCount;
  }
  
  
/**
   * 取得当前缓存路径值,所对应的路径
   * 
@param  pathNumber int 该路径为第几条路径
   * 
@return  String  路径字符串
   
*/
  
public   static  String getCurrentPathPoint( int  pathNumber){
    StringBuffer pathPointBuffer 
=   new  StringBuffer( " Path "   +  pathNumber  +   " :(0,0) " );
    
int  zeroCount  =   0 ;
    
int  oneCount  =   0 ;
    
for  ( int  i  =   0 ; i  <   2 * nValue; i ++ ){
      
if  (binaryArray[i]  ==   1 ){
        oneCount
++ ;
      } 
else  {
        zeroCount
++ ;
      }
      pathPointBuffer.append(
" -( "   +  oneCount  +   " , "   +  zeroCount  +   " ) " );
    }
    
return  pathPointBuffer.toString();
  }
  
  
public   static   int  getMinValue() {
    
return  minValue;
  }
  
public   static   int  getMaxValue() {
    
return  maxValue;
  }
}
 
AixClient3:一个简单的调用类,通过调用AixUtil3实现方案三的遍历 
package  qinysong.aix;

import  java.util.Date;

/**
 * <p>Title: 方案3的调用客户端,通过方案3工具类AixUtil3,遍历一个正方形的路径</p>
 * <p>Description: AIX 程序设计大赛---AIX正方形问题</p>
 * <p>Copyright: Copyright (c) 2006</p>
 * <p>Company: qinysong</p>
 * 
@author  zhaoqingsong
 * 
@version  1.0 
 
*/

public   class  AixClient3 {

  
public   static   void  main(String[] args) {
    System.out.println(
" AixClient3.main begin ...... " );
    System.out.println(
" AixClient3.main 方案3 " );
    Date beginTime3 
=   new  Date();
    System.out.println(
" beginTime3: "   +  beginTime3.toString());
    
// 初始化
     int  nValue  =   15 ;
    AixUtil3.initNValue(nValue);
    
int  minValue  =  AixUtil3.getMinValue(); 
    
int  maxValue  =  AixUtil3.getMaxValue(); 
    
int  availablePathCount  =   0 ;
    String pathPointString 
=   "" ;
    
// 从minValue到maxValue,遍历所有整数,如果字符串中1的个数等于nValue,即为一条有效路径
     for  ( int  i  =  minValue; i  <=  maxValue; i ++ ){
      
if  (AixUtil3.getOneBitCount(i)  ==  nValue){
        
++ availablePathCount;
        pathPointString 
=  AixUtil3.getCurrentPathPoint(availablePathCount);
        System.out.println(pathPointString);
      }
    }
    System.out.println(
" pathCount: "   +  availablePathCount);
    Date endTime3 
=   new  Date();
    System.out.println(
" end endTime3 :   "   +  endTime3.toString());
    System.out.println(
" 方案3所花时间毫秒:   "   +  (endTime3.getTime()  -  beginTime3.getTime()));
    System.out.println(
" AixClient3.main end   ...... " );
  }
}
 
 
 
 
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值