算法题--华为od机试考试(围棋的气、用连续自然数之和来表达整数、亲子游戏)

目录

围棋的气

题目描述

输入描述

示例1

输入

输出

解析

答案

用连续自然数之和来表达整数

题目描述

输入描述

输出描述

示例1

输入

输出

说明

示例2

输入

输出

解析

答案

亲子游戏

题目描述

输入描述

输出描述

示例1

输入

输出

说明

示例2

输入

输出

说明

备注

解析


围棋的气

考察hash、理解、二维数组

题目描述

围棋棋盘由纵横各19条线垂直相交组成,棋盘上一共19x19=361个交点,对弈双方一方执白棋,一方执黑棋,落子时只能将棋子置于交点上。

“气”是围棋中很重要的一个概念,某个棋子有几口气,是指其上下左右方向四个相邻的交叉点中,有几个交叉点没有棋子,由此可知:

1、在棋盘的边缘上的棋子最多有3口气(黑1),在棋盘角点的棋子最多有2口气(黑2),其它情况最多有4口气(白1)

2、所有同色棋子的气之和叫作该色棋子的气,需要注意的是,同色棋子重合的气点,对于该颜色棋子来说,只能计算一次气,比如下图中,黑棋一共4口气,而不是5口气,因为黑1和黑2中间红色三角标出的气是两个黑棋共有的,对于黑棋整体来说只能算一个气。

3、本题目只计算气,对于眼也按气计算,如果您不清楚“眼”的概念,可忽略,按照前面描述的规则计算即可。

现在,请根据输入的黑棋和白棋的坐标位置,计算黑棋和白起一共各有多少气?

输入描述

输入包括两行数据,如:

0 5 8 9 9 10

5 0 9 9 9 8

1、每行数据以空格分隔,数据个数是2的整数倍,每两个数是一组,代表棋子在棋盘上的坐标;

2、坐标的原点在棋盘左上角点,第一个值是行号,范围从0到18;第二个值是列号,范围从0到18。

示例1

输入

0 5 8 9 9 10

5 0 9 9 9 8

输出

15

解析

首先生成一个19*19的二维数组,这里注意new Array后用fill填值生成会导致对象的引用一致问题,需要用map解决。

这里需要设计棋盘每个点的对象,这里用value表示下得棋的颜色, 0 ,1,2表示空、黑、白,white和black属性用于表示是否已经计算过黑白棋的气。

然后只用通过for循环计算每个方向上的如果value为0且,当前计算的属性的值对应为true即可+1。这里注意如果棋下在边界需要考虑数组越界问题。

这里使用?.访问,当属性不存在时会返回undefined。

答案

function getWeiQiAir(str) {
    let [black, white] = str.split('\n')
    black = black.split(' ').map(Number)
    white = white.split(' ').map(Number)
    // value: 0 ,1,2表示空、黑、白,white和black属性用于表示是否已经计算过黑白棋的气。
    // 注意生成的二维数组不能直接用fill填{ value: 0, white: true, black: true }。这样会导致引用一致,改一个value,所有的value都会变。
    let qipan = new Array(19).fill(0).map(v => new Array(19).fill(0).map(v => ({ value: 0, white: true, black: true })))
    // 棋盘上下对应的棋
    let lenB = black.length
    for (let i = 0; i < lenB; i = i + 2) {
        qipan[black[i]][black[i + 1]].value = 1
    }
    let lenW = white.length
    for (let i = 0; i < lenW; i = i + 2) {
        qipan[white[i]][white[i + 1]].value = 2
    }
    let sum = 0
    // 计算黑棋的气
    for (let i = 0; i < lenB; i = i + 2) {
        let x = black[i]
        let y = black[i + 1]
        // 第一个条件判断某一个方向是否为空,第二个条件判断是否被当前颜色计算过
        // 注意如果棋下在边界需要考虑数组越界问题。这里使用?.访问,当属性不存在时会返回undefined
        if (qipan?.[x - 1]?.[y]?.value == 0 && qipan[x - 1][y].black) {
            qipan[x - 1][y].black = false
            sum++
        }
        if (qipan[x]?.[y - 1]?.value == 0 && qipan[x][y - 1].black) {
            qipan[x][y - 1].black = false
            sum++
        }
        if (qipan?.[x + 1]?.[y]?.value == 0 && qipan[x + 1][y].black) {
            qipan[x + 1][y].black = false
            sum++
        }
        if (qipan[x]?.[y + 1]?.value == 0 && qipan[x][y + 1].black) {
            qipan[x][y + 1].black = false
            sum++
        }
    }
    // 计算白棋的气
    for (let i = 0; i < lenW; i = i + 2) {
        let x = white[i]
        let y = white[i + 1]
        if (qipan?.[x - 1]?.[y]?.value == 0 && qipan[x - 1][y].white) {
            qipan[x - 1][y].white = false
            sum++
        }
        if (qipan[x]?.[y - 1]?.value == 0 && qipan[x][y - 1].white) {
            qipan[x][y - 1].white = false
            sum++
        }
        if (qipan?.[x + 1]?.[y]?.value == 0 && qipan[x + 1][y].white) {
            qipan[x + 1][y].white = false
            sum++
        }
        if (qipan[x]?.[y + 1]?.value == 0 && qipan[x][y + 1].white) {
            qipan[x][y + 1].white = false
            sum++
        }
    }
    return sum
}
console.log(getWeiQiAir(`0 5 8 9 9 10
5 0 9 9 9 8`))

用连续自然数之和来表达整数

考察数学,双指针

题目描述

一个整数可以由连续的自然数之和来表示。

给定一个整数,计算该整数有几种连续自然数之和的表达式,且打印出每种表达式

输入描述

一个目标整数T (1 <=T<= 1000)

输出描述

该整数的所有表达式和表达式的个数。如果有多种表达式,输出要求为:

自然数个数最少的表达式优先输出

每个表达式中按自然数递增的顺序输出,具体的格式参见样例。

在每个测试数据结束时,输出一行”Result:X”,其中X是最终的表达式个数。

示例1

输入

9

输出

9=9

9=4+5

9=2+3+4

Result:3

说明

整数9有三种表达方法

示例2

输入

10

输出

10=10

10=1+2+3+4

Result:2

解析

方法一:通过遍历加计算,假设有i个数合为目标数n,其中最小的数为m,即m,m+1,m+2,...,m+i-1的和为n,即i*m+1+2+...+i-1=n。故n减去1加到i-1的和

需要被m整除即可。

方法二:类似于双指针,用i和j指向头和尾(i<j),i一直加到j如果大于等于目标值时(等于的时候还需要记录结果),i加一,如果小于目标值时j+1,

当i和j都大于目标值除以2时结束循环。

答案

// 方法一
function continusInteger(n) {
    let res = [`${n}=${n}`]
    for (let i = 2; i < Math.floor(n / 2); i++) {
        // new Array(i).fill(0).reduce((t,v,i)=>t+i)表示1+2+...+i-1
        let tmp = n - new Array(i).fill(0).reduce((t, v, i) => t + i)
        let start = tmp / i
        // 找到最小的数start,拼接连续自然数加入结果数组中
        if (Number.isInteger(start)) {
            let str = `${n}=${start}`
            for (j = 1; j < i; j++) {
                str = str + `+${start + j}`
            }
            res.push(str)
        }
    }
    return `${res.join('\n')}\nResult:${res.length}`
}
// 方法二
function continusInteger(n) {
    if (n < 3) {
        return `${n}=${n}\nRestult:1`
    }
    let res = [`${n}=${n}`]
    let i = 1, j = 2
    sum = i + j
    while (i < n / 2 || j < n / 2) {
        if (sum < n) {
            j++
            sum = sum + j
        } else if (sum > n) {
            sum = sum - i
            i++
        } else {
            // 找到目标值记录
            let str = `${n}=${i}`
            for (let x = i + 1; x <= j; x++) {
                str = str + `+${x}`
            }
            res.push(str)
            j++
            sum = sum + j
        }
    }
    return `${res.join('\n')}\nResult:${res.length}`
}
console.log(continusInteger(9))
console.log(continusInteger(10))

亲子游戏

考察深度遍历、递归

题目描述

宝宝和妈妈参加亲子游戏,在一个二维矩阵(N*N)的格子地图上,宝宝和妈妈抽签决定各自的位置,地图上每个格子有不同的糖果数量,部分格子有障碍物。

游戏规则是妈妈必须在最短的时间(每个单位时间只能走一步)到达宝宝的位置,路上的所有糖果都可以拿走,不能走障碍物的格子,只能上下左右走。

请问妈妈在最短到达宝宝位置的时间内最多拿到多少糖果(优先考虑最短时间到达的情况下尽可能多拿糖果)。

输入描述

第一行输入为N,N标识二维矩阵的大小

之后N行,每行有N个值,表格矩阵每个位置的值

其中:

-3:妈妈

-2:宝宝

-1:障碍

=0:糖果数(0表示没有糖果,但是可以走)

输出描述

输出妈妈在最短到达宝宝位置的时间内最多拿到多少糖果,行末无多余空格

示例1

输入输出示例仅供调试,后台判题数据一般不包含示例

输入

4

3 2 1 -3

1 -1 1 1

1 1 -1 2

-2 1 2 3

输出

9

说明

此地图有两条最短路径可到宝宝位置,绿色线和黄色线都是最短路径6步,但是黄色拿到的糖果更多,9个

示例2

输入

4

3 2 1 -3

-1 -1 1 1

1 1 -1 2

-2 1 -1 3

输出

-1

说明

此地图妈妈无法到达宝宝位置

备注

地图最大5050

解析

1.用二维数组表示图中每个点,每个点为一个对象v属性对应每个点的数值,can属性对应是否可以经过。

2.用深度遍历来找出结果:

    1.首先f(start,end)表示从起点到终点获得的最短路劲已经最大糖果数。f(start,end)等于min(f(start-top,end),f(start-bottom,end),f(start-left,end),f(start-end,end))。其中start-top表示start位置向

上走一格后的位置。这里表示从4个方向走一格后到终点位置的值,取最短的一个路径,注意如果路径同样短的要取一个糖果多的,所以f(start,end)需要

返回2个结果一个为最短路径和最大的糖果数。

    2.找终点:

        1>当start和end对应的横、纵坐标之差的绝对值为1时,说明起点和终点相邻,即可以直接退出。

        2>当当前的步数已经大于等于已有成功的步数时,可以直接退出。

        3>每次走过的位置,把can属性设置为false,防止走回头路,当4个方向都走不了时,直接退出。

        4>每次走完后需要还原之前的步数、糖果数、起点坐标以及数组中的是否已经经过的属性can。

function getMinPath(str) {
    let arr = str.split('\n')
    let len = Number(arr.shift())
    let start = {}, end = {}
    // 用二维数组表示图中的每个点
    arr = arr.map((v, i) => v.split(' ').map((v, j) => {
        v = Number(v)
        // 记录起点和终点的位置
        if (v === -3) {
            start.x = i
            start.y = j
        }
        if (v === -2) {
            end.x = i
            end.y = j
        }
        return { v, can: true }
    }))
    let res = bfs(start, end, 0, 0, len, arr)
    if (res) {
        return res[1]
    }
    return -1
}
function bfs(start, end, step, candi, len, arr, min = Infinity, max = 0) {
    if (Math.abs(start.x - end.x) + Math.abs(start.y - end.y) === 1) {
        return [step, candi]
    }
    if (step >= min) {
        return
    }
    if (start.x + 1 < len) {
        if (arr[start.x + 1][start.y].v >= 0 && arr[start.x + 1][start.y].can) {
            start.x++
            step++
            candi += arr[start.x][start.y].v
            arr[start.x][start.y].can = false
            let r = bfs(start, end, step, candi, len, arr, min, max)
            if (r) {
                if (r[0] < min) {
                    // 当前解的步数小于已有的成功步数,
                    min = r[0]
                    max = r[1]
                } else if (r[0] === min && r[1] > max) {
                    // 当前解的步数等于已有的成功步数,糖果数大于已有成功步数的糖果数
                    判断当前解的
                    max = r[1]
                }
            }
            //还原
            start.x--
            step--
            candi -= arr[start.x][start.y].v
            arr[start.x][start.y].can = true
        }
    }
    if (start.x - 1 >= 0) {
        if (arr[start.x - 1][start.y].v >= 0 && arr[start.x - 1][start.y].can) {
            start.x--
            step++
            candi += arr[start.x][start.y].v
            arr[start.x][start.y].can = false
            let l = bfs(start, end, step, candi, len, arr, min, max)
            if (l) {
                if (l[0] < min) {
                    min = l[0]
                    max = l[1]
                } else if (l[0] === min && l[1] > max) {
                    max = l[1]
                }
            }
            //还原
            start.x++
            step--
            candi -= arr[start.x][start.y].v
            arr[start.x][start.y].can = true
        }
    }
    if (start.y + 1 < len) {
        if (arr[start.x][start.y + 1].v >= 0 && arr[start.x][start.y + 1].can) {
            start.y++
            step++
            candi += arr[start.x][start.y].v
            arr[start.x][start.y].can = false
            let t = bfs(start, end, step, candi, len, arr, min, max)
            if (t) {
                if (t[0] < min) {
                    min = t[0]
                    max = t[1]
                } else if (t[0] === min && t[1] > max) {
                    max = t[1]
                }
            }
            //还原
            start.y--
            step--
            candi -= arr[start.x][start.y].v
            arr[start.x][start.y].can = true
        }
    }
    if (start.y - 1 >= 0) {
        if (arr[start.x][start.y - 1].v >= 0 && arr[start.x][start.y - 1].can) {
            start.y--
            step++
            candi += arr[start.x][start.y].v
            arr[start.x][start.y].can = false
            let b = bfs(start, end, step, candi, len, arr, min, max)
            if (b) {
                if (b[0] < min) {
                    min = b[0]
                    max = b[1]
                } else if (b[0] === min && b[1] > max) {
                    max = b[1]
                }
            }
            //还原
            start.y++
            step--
            candi -= arr[start.x][start.y].v
            arr[start.x][start.y].can = true
        }
    }
    if (min !== Infinity) {
        return [min, max]
    }
}
console.log(getMinPath(`4
3 2 1 -3
1 -1 1 1
1 1 -1 2
-2 1 2 3`))
console.log(getMinPath(`4
3 2 1 -3
-1 -1 1 1
1 1 -1 2
-2 1 -1 3`))

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/688212.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

plsql导入excel

1.建临时表&#xff1a;&#xff08;字段对应excel表头&#xff09; create table temp_old_table(atomname nvarchar2(4000), --原子名称koujingname nvarchar2(4000) --供应商名称);2.Plsql–>工具&#xff08;tool&#xff09;–>ODBC导入器&#xff08;ODBC Impo…

使用AutoGen框架进行多智能体协作:AI Agentic Design Patterns with AutoGen

AI Agentic Design Patterns with AutoGen 本文是学习https://www.deeplearning.ai/short-courses/ai-agentic-design-patterns-with-autogen/ 这门课的学习笔记。 What you’ll learn in this course In AI Agentic Design Patterns with AutoGen you’ll learn how to buil…

【JMeter接口测试工具】第二节.JMeter基本功能介绍(中)【入门篇】

文章目录 前言四、信息头管理器五、Jmeter参数化 5.1 用户自定义的变量 5.2 csv批量添加 5.3 用户参数 5.4 随机数函数 5.5 计数器函数 5.6 时间函数六、Jmeter断言 6.0 断言介绍 6.1 响应断言 6.2 大小断言 6.3 持续时间断…

【人工智能】第三部分:ChatGPT的应用场景和挑战

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

vue3+ts 拖拽容器边缘,改变容器宽度和高度

例如&#xff1a;我们的代码编辑器 终端与代码区&#xff0c;可以纵向拖拽&#xff0c;改变两个容器高度 目录与代码区可以横向拖拽&#xff0c;改变两个容器宽度 本文使用vue3tstailwindcss&#xff0c;把横向纵向整合在一起写了&#xff0c;也可以分开使用 utils目录下新建…

【C++课程学习】:C++入门(函数重载)

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;C课程学习 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 &#x1f308;函数重载&#xff1a; &#x1f349;1.参数个数不同&#xff1a; &#x1f349;2.参数…

语音深度鉴伪识别项目实战:基于深度学习的语音深度鉴伪识别算法模型(二)音频数据预处理及去噪算法+Python源码应用

前言 深度学习技术在当今技术市场上面尚有余力和开发空间的&#xff0c;主流落地领域主要有&#xff1a;视觉&#xff0c;听觉&#xff0c;AIGC这三大板块。 目前视觉板块的框架和主流技术在我上一篇基于Yolov7-LPRNet的动态车牌目标识别算法模型已有较为详细的解说。与AIGC相…

Java使用OpenCV计算两张图片相似度

业务&#xff1a;找出两个表的重复的图片。 图片在表里存的是二进制值&#xff0c;存在大量由于一些特殊情况例如扫描有差异&#xff0c;导致图片存的二进制值不同&#xff0c;但图片其实是一样来的。 所以找出两个表重复相同的图片&#xff0c;不可能只是单纯的比较二进制值…

java版B/S架构UWB人员定位系统源码spring boot+vue技术架构uwb定位装置-工业级UWB室内定位系统源码

java版B/S架构UWB人员定位系统源码spring bootvue技术架构uwb定位装置-工业级UWB室内定位系统源码 本套系统运用UWB定位技术&#xff0c;开发的高精度人员定位系统&#xff0c;通过独特的射频处理&#xff0c;配合先进的位置算法&#xff0c;可以有效计算复杂环境下的人员与物…

【MySQL】MySQL 图形化界面 - 使用说明(MySQL Workbench)

一、安装软件 Navicat&#xff0c;SQLyog 这些软件都不错&#xff0c;不过都需要收费&#xff0c;当然也有破解版。下面用 MySQL Workbench&#xff0c;它是官方提供的工具。 二、使用操作 这个软件本质是一个客户端&#xff0c;现在要让数据库能够远程登录。不过一般不会远程…

生活使用英语口语柯桥外语学校成人英语学习

● “自来水”英语怎么说&#xff1f; ● “自来水”的英语表达是&#xff1a;Running water或者Tap water. 例句&#xff1a; There are hot and cold running water in all the bedrooms. 所有的卧室里都有冷热自来水。 ● “热水”英文怎么水&#xff1f; ● 我们不管…

[经验] 羊肺怎么清洗才干净视频 #经验分享#学习方法#其他

羊肺怎么清洗才干净视频 1、羊肺怎么清洗才干净 羊肺是一种营养丰富的食材&#xff0c;含有丰富的蛋白质和维生素&#xff0c;是众多美食菜谱的重要原料之一。但是&#xff0c;由于羊肺的内部结构复杂&#xff0c;清洗起来比较麻烦。那么&#xff0c;如何清洗羊肺才能让它干净…

Excel 交叉表的格转成列,行转成格

Excel里交叉表的左表头是卡车号&#xff0c;上表头是工作&#xff0c;交叉格是工作编号。 ABCD1Truck NumberJob1Job2Job3271592859285928372395859282971473297159282971 要求&#xff1a;将交叉格转为列&#xff0c;左表头转为格。 ABC1297139585928272727137371473715726…

【Python】使用Gradio作为机器学习web服务器

在机器学习领域&#xff0c;模型的展示和验证是一个重要的环节。传统的模型展示方式往往需要复杂的Web开发知识&#xff0c;这对于许多机器学习研究者或数据科学家来说可能是一个挑战。然而&#xff0c;Gradio的出现为我们提供了一个简单而强大的解决方案&#xff0c;让我们能够…

麒麟v10系统arm64架构openssh9.7p1的rpm包

制作openssh 说明 理论上制作的多个rpm在arm64架构&#xff08;aarch64&#xff09;都适用 系统信息&#xff1a;4.19.90-17.ky10.aarch64 GNU/Linux 升级前备份好文件/etc/ssh、/etc/pam.d等以及开启telnet 升级后确认正常后关闭telnet 在之前制作过openssh-9.5p1基础上继续…

Python文本处理利器:jieba库全解析

文章目录 Python文本处理利器&#xff1a;jieba库全解析第一部分&#xff1a;背景和功能介绍第二部分&#xff1a;库的概述第三部分&#xff1a;安装方法第四部分&#xff1a;常用库函数介绍1. 精确模式分词2. 全模式分词3. 搜索引擎模式分词4. 添加自定义词典5. 关键词提取 第…

汽车尾气排放污染的解决方案

根据公安部截至2023年底的机动车市场保有量统计&#xff0c;燃油车市场仍有不少消费者拥趸&#xff1a;目前全国新能源汽车保有量仅占汽车总量的6.07%&#xff0c;而其中的纯电动汽车保有量占比仅为76.05%。 汽车尾气排放污染已成为城市主要污染源之一。据统计显示&#xff0c…

代码随想录算法训练营Day17|404.左叶子之和 110.平衡二叉树 222.完全二叉树的节点个数

404.左叶子之和 1、这道题需要统计出所有左叶子结点的值的和&#xff0c;首先要明确左叶子节点指的左右孩子节点均为null的左节点。如上图就是4和6. 2.但是光凭叶子结点本身是无法判定左叶子的&#xff0c;因为左右孩子都是null&#xff0c;所以要从上一层节点往下判定。所以判…

Python下载库

注&#xff1a;本文一律使用windows讲解。 一、使用cmd下载 先用快捷键win R打开"运行"窗口&#xff0c;如下图。 在输入框中输入cmd并按回车Enter或点确定键&#xff0c;随后会出现这个画面&#xff1a; 输入pip install 你想下载的库名&#xff0c;并按回车&…

玩转微服务-GateWay

目录 一. 背景二. API网关1. 概念2. API网关定义3. API网关的四大职能4. API网关分类5. 开源API网关介绍6. 开源网关的选择 三. Spring Cloud Gateway1. 文档地址2. 三个核心概念3. 工作流程4. 运行原理4.1 路由原理4.2 RouteLocator 5. Predicate 断言6. 过滤器 Filter6.1. 过…