当前位置: 首页 > wzjs >正文

个人网站网页设计模板app定制开发

个人网站网页设计模板,app定制开发,初中生代表性设计制作作品图片,赣州网页设计网给定一个mxn的矩阵,由若干字符X和O构成,X表示该处已被占据,O表示该处空闲,请找到最大的单入口空闲区域 解释: 空闲区域是由连通的O组成的区域,位于边界的O可以构成入口.单入口空闲区域即有且只有一个位于边界的O作为…

给定一个mxn的矩阵,由若干字符'X'和'O'构成,'X'表示该处已被占据,'O'表示该处空闲,请找到最大的单入口空闲区域

解释:

空闲区域是由连通的'O'组成的区域,位于边界的'O'可以构成入口.单入口空闲区域即有且只有一个位于边界的'O'作为入口的由连通的'O'组成的区域.如果两个元素在水平或垂直方向相邻,则称它们是“连通”的

输入描述

第一行输入为两个数字,第一个数字为行数 m,第二个数字为列数 n,两个数字以空格分隔,

1<=m,n<=200.

剩余各行为矩阵各行元素,元素为'X'或'O',各元素间以空格分隔

输出描述

若有唯一符合要求的最大单入口空闲区域,输出三个数字

第一个数字为入口行坐标(0~m-1)
第二个数字为入口列坐标(0~n-1)
第三个数字为区域大小
三个数字以空格分隔;

若有多个符合要求,则输出区域大小最大的,若多个符合要求的单入口区域的区域大小相同,
则此时只需要输出区域大小,不需要输出入口坐标

若没有,输出 NULL

用例

输出输出
4 4
X X X X
X O O X
X O O X
X O X X
3 1 5

思考一(DFS)

        矩阵搜索问题,可以通过 DFS 或 BFS 解决。先看 DFS,要求统计单入口区域大小,那么可以围绕着矩阵边界寻找元素为‘O'的位置作为起点进行深度优先搜索。每个入口表示一次 DFS,过程中我们要统计区域大小,即元素 ’O' 的数量,怎么把这个数量和当前 DFS 进行关联呢?由于一般 DFS 是递归实现,这里也是采用递归实现 DFS 过程,因此我们每递归调用一次 dfs 函数就会开启一个临时栈,这个栈在结束时会销毁内部关联的数据,可以通过引用参数把函数栈的计算数据保存起来。也就是说可以在DFS起点的时候就传递一个对象或数组存放当前 DFS 起点坐标(及入口坐标)、区域大小 count 初始化参数值为 0,然后搜索过程中不断更新这个对象的属性值。当我们搜索到另一个位于边界上的元素'O'时,表明当前 DFS 搜索已经包含了两个入口,显然不满足单入口要求,需要丢弃当前搜索结果,终止本次 DFS,但并不能立即终止递归。递归搜索是分叉的树状结构,在某个分支节点上遇到了该结束的状态,但是其它分支依然在进行展开,我们没法立即通知它们完结销毁整棵递归树 。 这时候需要把那个引用传递给 dfs 函数的对象参数更新下,比如把 count 置为 -1,在递归函数中判断如果 count 是 -1 就回溯,因为引用传递的参数对象是共享的,因此所有递归调用的函数栈中都能看到相同的状态,都立即回溯,最终整棵递归树就销毁了。如果搜索整个过程顺利没有遇到第二个入口,那么最终这次 DFS 的统计的区域大小 count 和 起点坐标 x,y 都要与全局的结果进行比较更新,保存最大的count,已存在相同大小的 count 就更新全局变量 isMult 为 true 表示存在多个相同大小的单入口区域。但实际实现感觉这种通过函数的引用参数保存搜索结果有时候处理逻辑写起来并不是很容易且直观。所以还有一种通过全局的字典变量来记录每次 DFS 搜索结果更简单些,就像记录元素是否被访问过的备忘录变量 visited数组。用入口的位置坐标以空格作为分割拼接字符串作为字典的 key,JavaScript 就用 Map 来处理,用区域大小 count 作为字典的值。这样 dfs函数只要传递当前元素位置坐标 和 起始位置[x,y] 就行了,根据key 来更新对应的数据。最后统计字典中最大的数值,有重复的最大的就只输出最大数值,没有重复最大值也把入口坐标输出,字典为空表示没找到单入口区域输出 NULL。

算法过程

  1. 输入处理:读取网格尺寸 m 和 n,然后读取整个网格内容
  2. 初始化数据结构:创建与网格大小相同的 visited 数组并初始化为 false,创建入口映射 entryMap
  3. 边界遍历
    • 遍历左右边界(列 0 和列 n-1),对未访问的 'O' 点启动 DFS
    • 遍历上下边界(行 0 和行 m-1),对未访问的 'O' 点启动 DFS
  4. DFS 搜索
    • 标记当前点为已访问
    • 若当前点是边界点且非起点,删除当前入口并返回
    • 递归搜索上下左右四个方向的相邻点
  5. 结果处理
    • 遍历所有合法入口区域,找出最大区域
    • 若存在多个最大区域,仅输出大小
    • 否则输出坐标和大小
      时间复杂度:O (mn) ,空间复杂度:O (mn)

参考代码

function solution() {const [m, n] = readline().split(" ").map(Number);const mtx = [];for (let i = 0; i < m; i++) {mtx.push(readline().split(" "));}const visited = Array.from({ length: m }, () => new Array(n).fill(false));const entryMap = new Map();const dfs = function (i, j, [x, y]) {// 已访问过或者当前元素不可通行直接返回if (visited[i][j] || mtx[i][j] === "X") return;visited[i][j] = true;const key = `${x} ${y}`;if (!entryMap.has(key)) return; // key 被干掉了,好吧...entryMap.set(key, entryMap.get(key) + 1); // 统计区域大小if ((i !== x || j !== y) && (i === 0 || i === m-1 || j === 0 || j === n-1)) {// 找到了另一个入口,删除当前起点,区域作废!entryMap.delete(key);return;}if (i - 1 >= 0) {// 判断左侧非边界区域是否可搜索dfs(i - 1, j, [x, y]);}if (i + 1 < m) {// 判断右侧非边界区域是否可搜索dfs(i + 1, j, [x, y]);}if (j - 1 >= 0) {// 判断上方非边界区域是否可搜索dfs(i, j - 1, [x, y]);}if (j + 1 < n) {// 判断下方非边界区域是否可搜索dfs(i, j + 1, [x, y]);}};// 固定列,寻找左右边界上的入口开始搜索let key;for (let i = 0; i < m; i++) {if (!visited[i][0] && mtx[i][0] === "O") {key = `${i} 0`;entryMap.set(key, 0);dfs(i, 0, [i, 0]);}if (!visited[i][n-1] && mtx[i][n-1] === "O") {key = `${i} ${n-1}`;entryMap.set(key, 0);dfs(i, n-1, [i, n-1]);}}// 固定行, 寻找上下边界上的入口开始搜索for (let i = 0; i < n; i++) {if (!visited[0][i] && mtx[0][i] === "O") {key = `0 ${i}`;entryMap.set(key, 0);dfs(0, i, [0, i]);}if (!visited[m - 1][i] && mtx[m - 1][i] === "O") {key = `${m-1} ${i}`;entryMap.set(key, 0);dfs(m-1, i, [m-1, i]);}}// console.log(entryMap);if (entryMap.size === 0) {console.log('NULL');return;}let maxSize = 0;let coordinate = undefined;let isMult = false;for (let [k, v] of entryMap) {if (coordinate) {if (v > maxSize) {maxSize = v;coordinate = k;isMult = false;} else if (v === maxSize) {isMult = true;}} else {maxSize = v;coordinate = k;}}if (isMult) {console.log(maxSize);} else {console.log(coordinate + ' ' + maxSize);}
}const cases = [`4 4
X X X X
X O O X
X O O X
X O X X`,`4 5X X X X XO O O O XX O O O XX O X X O`,`5 4X X X XX 0 0 0X 0 0 0X 0 0 XX X X X`,`5 4X X X XX O O OX X X XX O O OX X X X`
];let caseIndex = 0;
let lineIndex = 0;const readline = (function () {let lines = [];return function () {if (lineIndex === 0) {lines = cases[caseIndex].trim().split("\n").map((line) => line.trim());}return lines[lineIndex++];};
})();cases.forEach((_, i) => {caseIndex = i;lineIndex = 0;solution();
});

思考二(BFS)

有了上面的 DFS 解法基础,BFS 实现就很简单了,只用修改下搜索的方式,队列存储要遍历的元素,迭代访问队列中的每个元素进行统计直至队列为空,bfs 函数直接返回单入口区域大小,对于非单入口区域返回 0 。

算法过程

  1. 输入处理:读取网格尺寸 m 和 n,然后读取整个网格内容
  2. 初始化数据结构:创建与网格大小相同的 visited 数组并初始化为 false,创建入口映射 entryMap
  3. 边界遍历
    • 遍历左右边界(列 0 和列 n-1),对未访问的 'O' 点启动 BFS
    • 遍历上下边界(行 0 和行 m-1),对未访问的 'O' 点启动 BFS
  4. BFS 搜索
    • 初始化队列并将起点加入队列
    • 当队列不为空时:
      • 取出队首元素,若已访问或为 'X' 则跳过
      • 标记当前点为已访问
      • 若当前点是边界点且非起点,清空计数器并终止 BFS
      • 计数器加 1
      • 将上下左右四个方向的合法相邻点加入队列
    • 返回区域大小(若发现多入口则为 0)
  5. 结果处理
    • 遍历所有合法入口区域,找出最大区域
    • 若存在多个最大区域,仅输出大小
    • 否则输出坐标和大小
      时间复杂度:O (mn) ,空间复杂度:O (mn)

参考代码

function solution() {const [m, n] = readline().split(" ").map(Number);const mtx = [];for (let i = 0; i < m; i++) {mtx.push(readline().split(" "));}const visited = Array.from({ length: m }, () => new Array(n).fill(false));const entryMap = new Map();const bfs = function (queue, [x, y]) {let count = 0;while (queue.length) {let [i, j] = queue.shift();if (visited[i][j] || mtx[i][j] === 'X') continue;visited[i][j] = true;if ((i !== x || j !== y) && (i === 0 || i === m-1 || j === 0 || j === n-1)) {// 找到了另一个入口,停止迭代,区域作废!count = 0;break;}count++;if (i-1 >= 0) {queue.push([i-1, j]);}if (i+1 < m) {queue.push([i+1, j]);}if (j-1 >= 0) {queue.push([i, j-1]);}if (j+1 < n) {queue.push([i, j+1]);}}return count;};// 固定列,寻找左右边界上的入口开始搜索for (let i = 0; i < m; i++) {if (!visited[i][0] && mtx[i][0] === "O") {entryMap.set(`${i} 0`, bfs([[i, 0]], [i, 0]));}if (!visited[i][n-1] && mtx[i][n-1] === "O") {entryMap.set(`${i} ${n-1}`, bfs([[i, n-1]], [i, n-1]));}}// 固定行, 寻找上下边界上的入口开始搜索for (let i = 0; i < n; i++) {if (!visited[0][i] && mtx[0][i] === "O") {entryMap.set(`0 ${i}`, bfs([[0, i]], [0, i]));}if (!visited[m - 1][i] && mtx[m - 1][i] === "O") {entryMap.set(`${m-1} ${i}`, bfs([[m-1, i]], [m-1, i]));}}// console.log(entryMap);if (entryMap.size === 0) {console.log('NULL');return;}let maxSize = 0;let coordinate = undefined;let isMult = false;for (let [k, v] of entryMap) {if (coordinate) {if (v > maxSize) {maxSize = v;coordinate = k;isMult = false;} else if (v === maxSize) {isMult = true;}} else {maxSize = v;coordinate = k;}}if (isMult) {console.log(maxSize);} else {console.log(coordinate + ' ' + maxSize);}
}const cases = [`4 4
X X X X
X O O X
X O O X
X O X X`,`4 5X X X X XO O O O XX O O O XX O X X O`,`5 4X X X XX 0 0 0X 0 0 0X 0 0 XX X X X`,`5 4X X X XX O O OX X X XX O O OX X X X`
];let caseIndex = 0;
let lineIndex = 0;const readline = (function () {let lines = [];return function () {if (lineIndex === 0) {lines = cases[caseIndex].trim().split("\n").map((line) => line.trim());}return lines[lineIndex++];};
})();cases.forEach((_, i) => {caseIndex = i;lineIndex = 0;solution();
});

http://www.dtcms.com/wzjs/47641.html

相关文章:

  • 琴行网站开发学术论文南宁seo外包平台
  • 百度广告标识西安seo外包行者seo06
  • 虚拟主机网站源码目前引流最好的app
  • 网站建设及优化的策划书seo优化方向
  • 网站建设动态实训报告一份完整的营销策划书
  • 做百度联盟怎么才能创建多个网站windows优化大师是系统软件吗
  • 重庆网站建设公司有哪些内容广告公司网站
  • 腾讯企点是什么软件网站优化方案设计
  • 做网站需要代码么百度网站排名查询
  • 幼儿园建设网站企业官网独立站搭建要多少钱
  • 长沙建个网站一般需要多少钱中国搜索
  • 58同城类似的网站怎么做关键词的选取原则
  • 中山商城型网站建设怎么推广app让人去下载
  • qq推广文案怎么写seo运营
  • http做轮播图网站广告公司营销策划方案
  • 微网站 免费模板百度seo关键词排名优化教程
  • 外贸企业官网建站一个新品牌如何推广
  • 有官网建手机网站吗关键词优化心得
  • 网站怎样做自适应分辨率大小海淀网站建设公司
  • 唐山制作手机网站深圳市龙华区
  • 南京谷歌优化中小企业网站优化
  • 市政府网站建设方案如何在百度推广自己
  • 简述网页制作的基本流程搜索引擎优化岗位
  • 自适应网站功能中国站长之家网站
  • 南昌做网站哪家便宜换友情链接的网站
  • 班级网站怎么做ppt网站seo技术
  • 在什么网站上可以做免费广告品牌营销策划案例ppt
  • wordpress 语言包编辑如何提升网站seo排名
  • 租用外国服务器赌博网站建设淘宝指数查询
  • wordpress封面图插件外链seo服务