一道网易笔试题

来源:互联网 发布:单片机芯片 编辑:程序博客网 时间:2024/05/16 18:03
题目描述如下:
 现有一个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
代码实现如下(该实现方法基于思路一):

packageorg.min.algorithm;

importjava.util.ArrayList;

importjava.util.LinkedList;

importjava.util.List;

importjava.util.Random;

importjava.util.Scanner; 

publicclassMaxWeightRoad

{

   publicstatic void main(String[] args)

   {

       intm = 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 = newint[m][n];//创建mn列的棋盘,存放格中的权值  

       Random random =newRandom();

       //初始化棋盘中的格子,权值为随机生成的整数

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

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

           {

               checkerboard[i][j] = random.nextInt(30) -10;//随机生成-10~20之间的整数

           }

      //构建棋盘的n个有向图,用Node数据结构代表每个格子

       Listroots =newArrayList();

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

       {

           introw = 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;

       intweight =0;

       for(List nl: roadslist)

       {

           inttemp =0;

           for(Node nd: nl)

           {

               temp += nd.getWeight();

           }

           if(weight< temp)

           {

               weight = temp;

               mn = nl;

           }

       }     

      //打印结果

      intmaxweight= 0;

      for(Node de: mn)

       {

           maxweight +=de.getWeight();

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

       }

      System.out.println("\n最长路径权值之和为:"+maxweight);

   }

   //深度优先搜索求权值之和最长的路径

   publicstatic void getMaxRoad(Node node, List list)

   {

       intmaxweight= 0;

       Listtemplist =newLinkedList();    

       templist.add(node);

           

      while()

   }  

   //创建有向图

   publicstatic void createGraph(Node node,int[][]checkerboard)

   {

       //得到棋盘的边界

       intheight =checkerboard[0].length;

       intwidth =checkerboard.length;

       

       //获取当前格子的所在的行和列

       introw =node.getRow();

       intcow =node.getCow();

       

       inttemprow =row;

       inttempcow =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);

       }

       

   }

}

classNode

{

   privateintrow;//格子在棋盘中第几行

   privateintcow;//格子在棋盘中第几列

   privateintweight;//格子中的权值

   privateList branch;

   

   publicNode(introw, intcow, intweight)

   {

       this.row=row;

       this.cow=cow;

       this.weight=weight;

       this.branch=newLinkedList();

   }

   

   publicintgetRow()

   {

       returnrow;

   }

   publicintgetCow()

   {

       returncow;

   }

   publicintgetWeight()

   {

       returnweight;

   }

   publicListgetBranch()

   {

       returnbranch;

   }  

   publicStringtoString()

   {

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

   }

}

0 0
原创粉丝点击