您的位置:首页 > 其它

一道网易笔试题

2015-10-08 08:39 357 查看
题目描述如下:
 现有一个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
class
MaxWeightRoad
{
   public
static
void
main(String[] args)
   {
       int
m = 0, n= 0;//m行n列的棋盘
       Scanner in =
newScanner(System.in);
       
       System.out.print("请输入棋盘行数m:");
       m = in.nextInt();
       
       System.out.print("请输入棋盘列数n:");
       n = in.nextInt();  
       int[][]checkerboard
= new
int
[m]
;//创建m行n列的棋盘,存放格中的权值  
       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;
               m
11abf
n = 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
+")";
   }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: