目录

题目:

答:

1建立数学模型

2求解


题目:

一个简易吃豆人游戏,假设有一个m*n的棋盘(0<m, n<1000),棋盘格的坐标轴左上角是(0, 0),右下角是(m-1, n-1)。除了(0, 0)外,每个棋盘格上都放有一些豆子。吃豆人初始位置在(0, 0),每次只能向右或向下行动一格,并吃掉该格上的豆子,现在需要求一条路线,使吃掉的豆子的总数最大。请写一个函数计算这条路线以及吃掉的豆子数量,要求计算速度尽可能快,并且给出算法的时间复杂度。如果有多条等价路线,任意给出一条即可。

答:

解答本题分如下两步:1建立数学模型;2求解。

1建立数学模型

将这个m*n的棋盘(左图)抽象为图论中的有向无环图(缩写为DAG,右图)。

棋盘中的每个格子对应有向无环图的一个顶点,指向该顶点的边的权重等于该顶点的豆子数(比如,指向棋盘格子b的边,权重等于b,以此类推)。由于吃豆人只能向右或者向下移动,所以水平方向的边只能从左向右,垂直方向的边只能从上到下,如上图所示。由于这个限制,导致从任何一点出发,不论采取何种路径,都不会回到出发点,所以这个图是无环图。

由于棋盘中的每个格子对应有向无环图的一个顶点,所以有向无环图的水平方向的顶点数等于棋盘水平方向的格子数m,而水平方向的边数比顶点数少1,所以是m-1;有向无环图的垂直方向的顶点数等于棋盘垂直方向的格子数n,所以有向无环图的垂直方向的顶点数是n,垂直方向的边数是n-1。顶点总数为m*n。而边总数为(m-1)*(n-1)。

搜索吃豆人吃豆最多路线的问题就变成了搜索DAG最长路径的问题。此类问题的复杂度是O(边数+顶点数),故为O(m*n)

2求解

Longest Path in a Directed Acyclic Graph - GeeksforGeeks提供了示例代码解决此类问题。在此示例基础上略作修改,考虑如下棋盘,其格子中的数字代表格子内豆子数目:

根据前面的分析,数学模型对应一个顶点数为4 * 3= 12的DAG。

采用如下代码求解:

// A C++ program to find single source longest distances// in a DAG#include <iostream>#include <limits.h>#include <list>#include <stack>#define NINF INT_MINusing namespace std;// Graph is represented using adjacency list. Every// node of adjacency list contains vertex number of// the vertex to which edge connects. It also// contains weight of the edgeclass AdjListNode {int v;int weight;public:AdjListNode(int _v, int _w){v = _v;weight = _w;}int getV() { return v; }int getWeight() { return weight; }};// Class to represent a graph using adjacency list// representationclass Graph {int V; // No. of vertices'// Pointer to an array containing adjacency listslist<AdjListNode>* adj;list<int>        *   pPath;// A function used by longestPathvoid topologicalSortUtil(int v, bool visited[],stack<int>& Stack);public:Graph(int V); // Constructor~Graph(); // Destructor// function to add an edge to graphvoid addEdge(int u, int v, int weight);// Finds longest distances from given source vertexvoid longestPath(int s);};Graph::Graph(int V) // Constructor{this->V = V;adj = new list<AdjListNode>[V];pPath = new list<int>[V];}Graph::~Graph() // Destructor{delete[] adj;delete[] pPath;}void Graph::addEdge(int u, int v, int weight){AdjListNode node(v, weight);adj[u].push_back(node); // Add v to u's list}// A recursive function used by longestPath. See below// link for details// https:// www.geeksforgeeks.org/topological-sorting/void Graph::topologicalSortUtil(int v, bool visited[],stack<int>& Stack){// Mark the current node as visitedvisited[v] = true;// Recur for all the vertices adjacent to this vertexlist<AdjListNode>::iterator i;for (i = adj[v].begin(); i != adj[v].end(); ++i) {AdjListNode node = *i;if (!visited[node.getV()])topologicalSortUtil(node.getV(), visited, Stack);}// Push current vertex to stack which stores topological// sortStack.push(v);}// The function to find longest distances from a given vertex.// It uses recursive topologicalSortUtil() to get topological// sorting.void Graph::longestPath(int s){stack<int> Stack;int * dist = new int[V];// Mark all the vertices as not visitedbool* visited = new bool[V];for (int i = 0; i < V; i++)visited[i] = false;// Call the recursive helper function to store Topological// Sort starting from all vertices one by onefor (int i = 0; i < V; i++)if (visited[i] == false)topologicalSortUtil(i, visited, Stack);// Initialize distances to all vertices as infinite and// distance to source as 0for (int i = 0; i < V; i++){pPath[s].clear();dist[i] = NINF;}dist[s] = 0;pPath[s].push_back(s);// Process vertices in topological orderwhile (Stack.empty() == false) {// Get the next vertex from topological orderint u = Stack.top();Stack.pop();// Update distances of all adjacent verticeslist<AdjListNode>::iterator i;if (dist[u] != NINF) {for (i = adj[u].begin(); i != adj[u].end(); ++i){if (dist[i->getV()] < dist[u] + i->getWeight()){//更新与u相连的各个顶点到s的距离dist[i->getV()] = dist[u] + i->getWeight();//更新具体路径pPath[i->getV()].assign(pPath[u].begin(), pPath[u].end());pPath[i->getV()].push_back(i->getV());}  }}}// Print the calculated longest distancesfor (int i = 0; i < V; i++){cout << "length: ";(dist[i] == NINF) ? cout << "unReachable" : cout << dist[i];cout<< endl;cout << "path: ";for (const auto & item : pPath[i]){cout << item << " ";}cout << endl;}delete [] visited;delete [] dist;delete [] pPath;}// Driver program to test above functionsint main(){// Create a graph given in the above diagram.Graph g(12);g.addEdge(0, 1, 1);g.addEdge(0, 4, 3);g.addEdge(1, 2, 2);g.addEdge(1, 5, 5);g.addEdge(2, 3, 4);g.addEdge(2, 6, 1);//g.addEdge(3, 4, 0);//3号顶点处于棋盘最右g.addEdge(3, 7, 2);g.addEdge(4, 5, 5);g.addEdge(4, 8, 1);g.addEdge(5, 6, 1);g.addEdge(5, 9, 1);g.addEdge(6, 7, 2);g.addEdge(6, 10, 3);//g.addEdge(7, 8, 0);//7号顶点处于棋盘最右,不能再向右了g.addEdge(7, 11, 2);g.addEdge(8, 9, 1);//g.addEdge(8, 8, 1);g.addEdge(9, 10, 3);//g.addEdge(9, 9, 1);g.addEdge(10, 11, 2);//g.addEdge(10, 10, 3);//g.addEdge(11, 8, 0);//11号顶点处于棋盘最右,不能再向右了//g.addEdge(11, 11, 2); //11号顶点处于棋盘最下int s = 0;cout << "Following are longest distances from ""source vertex "<< s << " \n";g.longestPath(s);cin.get();return 0;}

在上面的问题中,采用0-11标记棋盘的格子:

结果:

可见,最长路径是0-4-5-9-10-11,长度为14

算法的时间复杂度为O(顶点数+边数)。这里也就是O(m*n)

某车企笔试题解答(1)相关推荐

  1. 精选30道Java笔试题解答

    精选30道Java笔试题解答       都是一些非常非常基础的题,是我最近参加各大IT公司笔试后靠记忆记下来的,经过整理献给与我一样参加各大IT校园招聘的同学们,纯考Java基础功底,老手们就不用进 ...

  2. java笔试30_精选30道Java笔试题解答

    精选30道Java笔试题解答 1. 下面哪些是Thread类的方法() A start() B run() C exit() D getPriority() 答案:ABD 解析:看Java API d ...

  3. 百度2014研发类校园招聘笔试题解答

    http://blog.csdn.net/lanxuezaipiao/article/details/42915285 先总体说下题型,共有3道简答题,3道算法编程题和1道系统设计题,题目有难有易,限 ...

  4. 58同城秋招笔试题解答 --map模式按value进行排序

    求字符串中字母重叠的次数并按要求输出(笔试题) 题目描述: 给定一个字符串,求出字母重叠出现的次数,最后按字典格式输出. 输入示例: aaabccbbbfffaddbaa 输出示例: a : 5 b ...

  5. Java笔试题解答和部分面试题

    面试类  银行类的问题 问题一:在多线程环境中使用HashMap会有什么问题?在什么情况下使用get()方法会产生无限循环? HashMap本身没有什么问题,有没有问题取决于你是如何使用它的.比如,你 ...

  6. 2015 阿里校招笔试题解答

    将define 在第三行展开,第二个是一个int 型变量 1.如果const位于*号的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量. 2.如果const位于*号的右侧,const就 ...

  7. 阿里笔试题解答(一)

     n从1开始,每个操作可以选择对n加1,或者对n加倍.如果目标数为2013,最少需要____个操作. 此题比较简单,使用逆向思维,2013的前一步骤必然是加1操作. 简单的归纳:如果是奇数,就进行 ...

  8. 一道笔试题引发的Promise笔记

    前言 近来参加校招笔试,发现有好几道关于Promise的题目.然而我都没有了解过.所以,这篇文章以网易笔试的一道题开始,记录关于Promise的那些事. 文章地址:http://lsxj615.com ...

  9. 转贴:雅虎公司C#笔试题,看看你能解答多少

    这是刚在在网上看到了,觉得这些题目出得真不错,能考出一个程序员的基本功.所以先发在这里,做个备份,以后慢慢来做(偶好像只能免强及格哦,呵呵,关于网络的题目太多了,偶不太熟啊)- ----------- ...

  10. 华为2018届校招技术岗笔试题及个人解答

    前言 昨天(9.13)参加了华为2018届的技术岗笔试,特此总结一下笔试的题目和我个人的解答思路. 笔试题一共是三道编程题,大致是数值反向输出,比较和排序,相对较基础. PS:由于没有截图,所以题目是 ...

最新文章

  1. c3074 无法使用带圆括号的_助力带分类简介
  2. JAVA 解析JSON数据
  3. Shorten command line 解决方案
  4. mysql未提交事务sql_MySQL如何找出未提交事务的SQL浅析
  5. JDK1.10+scala环境的搭建之linux环境(centos6.9)
  6. 输出cglib以及jdk动态代理产生的class文件
  7. 历史上的昨天和今天(zz)
  8. 如何在 Mac 上查找路由器 IP 地址?
  9. C语言 SDK编程之通用控件的使用--ListView
  10. java中常用的类——Object类
  11. 【Git】Failed to connect to github.com port 443 after 21092 ms: Connection refused
  12. 2019春节防坑指南之抢票陷阱
  13. Outlook添加新浪邮箱时的配置细节——登录密码
  14. 《零基础学C语言》光盘内容
  15. 海思lowlevel_init.S简单分析
  16. 数据库(Mysql)学习
  17. 小米软件研发工程师面试
  18. Nginx-Lua-FastDFS-GraphicsMagick动态图片缩略图
  19. 2021年计算机专业工作规划,2021最新计算机课教学计划
  20. 【读书笔记】被讨厌的勇气之自卑感

热门文章

  1. 考研数学线上笔记(二):凯哥不定积分计算系列课程
  2. 02-微信小程序商城 顶部广告图片(微信小程序商城开发、小程序毕业设计、小程序源代码)(黄菊华-微信小程序开发教程)
  3. GoC语言学习(C/C++程序设计语言入门)
  4. Java编程思想阅读收获
  5. tx2使用远程开机后分辨率不正确
  6. matlab怎么实现循环码,利用Matlab实现循环码编码
  7. 博瑞GE博越缤瑞缤越车机安装任意APP第三方软件教程
  8. python环境配置教程
  9. yacc和lex细节解答以及实现反向自动微分
  10. vb.net 教程 11-1 打印组件 5 PrintPreviewDialog