一道網易筆試題

題目描述如下:
 現有一個m行n列的格子棋盤,每一個格子附有一個權值,權值可以爲正負零。現在要求找出一條走線,將一個棋子從第一行移到第m行,使得經過所有格子的權值之和最大,說明算法思想,給出具體的實現,並分析時間和空間複雜度,這條走棋路線需要滿足如下要求:
1)起始格子可以爲第1行的任意一個格子
2)終止格子可以爲第m行的任意一個格子
3)走棋招法要求不許後退,並滿足象棋中的兵路,士路,或者馬路,也即:
對於線路中一步走棋(X1,Y1),(X2,Y2)滿足:
x2>x1(只需向前,不許後退)
x2=x1+1,y2=y1,兵路,直行
或者
x2=x1+1,y2=y1-1或者y2=y1+1,士路,斜行
或者
x2=x1+1,y2=y1-2或者y2=y1+2,馬路,橫向‘日’字
或者
x2=x1+2,y2=y1-1或者y2=y1+1,馬路,縱向‘日’字
如圖1所示:
                    
             圖1 
從權值爲8的方格開始,權值之和最大的走棋路線是:8 --> 9 --> 12 --> 19。

分析解答過程如下:
1)算法初步分析:要想一次性找到一條權值最大的路徑比較複雜,因爲起始位置有n個,而且對於每一個            位置而言,下一步的走法有5種(兩個橫日,兩個縱日,兵路)。因此對於這個情況比較多的尋找最長路徑            的問題,我們可以根據它的特點來建立一種數據結構。很顯然,我能想到的一種數據結構是有向圖。
2)算法詳細分析:建立有向圖這種結構我覺得有兩種思路
    a)思路一:將第一行的n個格子當做樹的根,這樣就可以創建n棵樹。樹中節點的分支數最多爲7,樹的                   葉節點均分佈在第m行,根節點都在第1行。
    b)思路二:建立一個虛根節點,另其權值爲0。該根節點的分支爲第一行的所有格子,共n棵子樹。
      建立了有向圖之後(如圖2所示,一棵樹的一部分),我們就可以按照深度優先搜索算法或者廣度優先搜索         算法來尋找一條權值最長的路徑。
              
                                                                           圖 2
代碼實現如下(該實現方法基於思路一):

package org.min.algorithm;

import java.util.ArrayList;

import java.util.LinkedList;

import java.util.List;

import java.util.Random;

import java.util.Scanner; 

public classMaxWeightRoad

{

   public static void main(String[] args)

   {

       int m = 0, n= 0;//mn列的棋盤

       Scanner in = newScanner(System.in);

       

       System.out.print("請輸入棋盤行數m:");

       m = in.nextInt();

       

       System.out.print("請輸入棋盤列數n:");

       n = in.nextInt();  

       int[][]checkerboard = new int[m][n];//創建mn列的棋盤,存放格中的權值  

       Random random = newRandom();

       //初始化棋盤中的格子,權值爲隨機生成的整數

       for(int i = 0; i< m; i++)

           for(int j = 0; j< n; j++)

           {

               checkerboard[i][j] = random.nextInt(30) -10;//隨機生成-10~20之間的整數

           }

      //構建棋盤的n個有向圖,用Node數據結構代表每個格子

       Listroots = newArrayList();

       for(int i = 0; i<checkerboard[0].length;i++)

       {

           int row = 0,cow = i, weight = checkerboard[0][i];

           Node node = newNode(row,cow, weight);

           createGraph(node, checkerboard);

           roots.add(node);

       }  

       List> roadslist = newArrayList>();//保存n個有向圖中權值之和最大的路徑,共n條路徑

       //求每個圖的權值之和最長的路徑,並將該路徑保存在roadslist

       for(Noderoot : roots)

       {

           Listroad = newLinkedList();

           getMaxRoad(root, road);

           roadslist.add(road);

       }      

       //得到路徑權值之和最大的路徑

       Listmn = null;

       int weight =0;

       for(List nl: roadslist)

       {

           int temp =0;

           for(Node nd: nl)

           {

               temp += nd.getWeight();

           }

           if(weight< temp)

           {

               weight = temp;

               mn = nl;

           }

       }     

      //打印結果

      int maxweight= 0;

      for(Node de: mn)

       {

           maxweight +=de.getWeight();

          System.out.print(de.toString() + "\t");

       }

      System.out.println("\n最長路徑權值之和爲:" +maxweight);

   }

   //深度優先搜索求權值之和最長的路徑

   public static void getMaxRoad(Node node, List list)

   {

       int maxweight= 0;

       Listtemplist = newLinkedList();    

       templist.add(node);

           

      while()

   }  

   //創建有向圖

   public static void createGraph(Node node, int[][]checkerboard)

   {

       //得到棋盤的邊界

       int height =checkerboard[0].length;

       int width =checkerboard.length;

       

       //獲取當前格子的所在的行和列

       int row =node.getRow();

       int cow =node.getCow();

       

       int temprow =row;

       int tempcow =cow;

       

       Node tempnode = null;

       

       //兵路x=x+1

       temprow = row + 1;

       if((temprow< width && temprow >=0) && (tempcow <height && tempcow >= 0))

       {

           tempnode = newNode(temprow, tempcow,checkerboard[temprow][tempcow]);

           node.getBranch().add(tempnode);

           createGraph(tempnode,checkerboard);

       }

       

       //日路x=x+1,y=y-1

       temprow = row + 1;

       tempcow = cow - 1;

       if((temprow< width && temprow >=0) && (tempcow <height && tempcow >= 0))

       {

           tempnode = newNode(temprow, tempcow,checkerboard[temprow][tempcow]);

           node.getBranch().add(tempnode);

           createGraph(tempnode,checkerboard);

       }

       //日路x=x+1,y=y+1

       temprow = row + 1;

       tempcow = cow + 1;

       if((temprow< width && temprow >=0) && (tempcow <height && tempcow >= 0))

       {

           tempnode = newNode(temprow, tempcow,checkerboard[temprow][tempcow]);

           node.getBranch().add(tempnode);

           createGraph(tempnode,checkerboard);

       }

       

       //馬路x=x+1,y=y-2

       temprow = row + 1;

       tempcow = cow - 2;

       if((temprow< width && temprow >=0) && (tempcow <height && tempcow >= 0))

       {

           tempnode = newNode(temprow, tempcow,checkerboard[temprow][tempcow]);

           node.getBranch().add(tempnode);

           createGraph(tempnode,checkerboard);

       }

       

       //馬路x=x+1,y=y+2

       temprow = row + 1;

       tempcow = cow + 2;

       if((temprow< width && temprow >=0) && (tempcow <height && tempcow >= 0))

       {

           tempnode = newNode(temprow, tempcow,checkerboard[temprow][tempcow]);

           node.getBranch().add(tempnode);

           createGraph(tempnode,checkerboard);

       }

       

       //馬路x=x+2,y=y-1

       temprow = row + 2;

       tempcow = cow - 1;

       if((temprow< width && temprow >=0) && (tempcow <height && tempcow >= 0))

       {

           tempnode = newNode(temprow, tempcow,checkerboard[temprow][tempcow]);

           node.getBranch().add(tempnode);

           createGraph(tempnode,checkerboard);

       }

       

       //馬路x=x+2,y=y+1

       temprow = row + 2;

       tempcow = cow + 1;

       if((temprow< width && temprow >=0) && (tempcow <height && tempcow >= 0))

       {

           tempnode = newNode(temprow, tempcow,checkerboard[temprow][tempcow]);

           node.getBranch().add(tempnode);

           createGraph(tempnode,checkerboard);

       }

       

   }

}

class Node

{

   private int row;//格子在棋盤中第幾行

   private int cow;//格子在棋盤中第幾列

   private int weight;//格子中的權值

   private List branch;

   

   public Node(int row, int cow, int weight)

   {

       this.row =row;

       this.cow =cow;

       this.weight =weight;

       this.branch =newLinkedList();

   }

   

   public int getRow()

   {

       return row;

   }

   public int getCow()

   {

       return cow;

   }

   public int getWeight()

   {

       return weight;

   }

   public ListgetBranch()

   {

       return branch;

   }  

   public StringtoString()

   {

       return "(" +row +"," +cow +")";

   }

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章