华为OD机考算法题:最远足迹

目录

题目部分

解读与分析

代码实现


题目部分

|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| | |
| 题目 | 最远足迹 |
| 题目说明 | 某探险队负责对地下洞穴进行探险。 探险队成员在进行探险任务时,随身携带的记录器会不定期地记录自身的坐标,但在记录的间隙中也会记录其他数据。探索工作结束后,探险队需要获取到某成员在探险过程中相对于探险队总部的最远的足迹位置。 1. 仪器记录坐标时,坐标的数据格式为(x,y),如(1,2)、(100,200),其中0<x<1000,0<y<1000。同时存在非法坐标,如(01,1)、(1,01),(0,100)属于非法坐标。 2. 设定探险队总部的坐标为(0,0),某位置相对总部的距离为:x * x+ y * y。 3. 若两个座标的相对总部的距离相同,则第一次到达的坐标为最远的足迹。 4. 若记录仪中的坐标都不合法,输出总部坐标(0,0)。 备注:不需要考虑双层括号嵌套的情况,比如sfsdfsd((1,2))。 |
| 输入描述 | 字符串,表示记录仪中的数据。 如:ferga13fdsf3(100,200)f2r3rfasf(300,400) |
| 输出描述 | 字符串,表示最远足迹到达的坐标。 如: (300,400) |
| 补充说明 | 无 |
| ------------------------------------------------------ ||
| 示例 | |
| 示例1 | |
| 输入 | ferg(3,10)a13fdsf3(3,4)f2r3rfasf(5,10) |
| 输出 | (5,10) |
| 说明 | 记录仪中的合法坐标有3个: (3,10), (3,4), (5,10),其中(5,10)是相距总部最远的坐标, 输出(5,10)。 |
| | |
| 示例2 | |
| 输入 | asfefaweawfaw(0,1)fe |
| 输出 | (0,0) |
| 说明 | 记录仪中的坐标都不合法,输出总部坐标(0,0) |
| | |


解读与分析

题目解读:

此题要求从输入字符串中过滤出所有合法的坐标,计算出最远坐标,并输出它。合法坐标的意思是:

  1. 首字母是'(',尾字母是')',中间是两个数字,用',' 隔开。
  2. 两个数字的首位都不能为 0(数字不能等于0,而且大于0的数字不能有前导 0)。
    如果不存在合法坐标,则输出 (0,0)。

关于非法坐标的判断是通过题目的样例总结出来的。
一种更好的出题方式是,使用概括的语言描述合法(或不合法)的情况,然后举例说明。否则,举例如果不能覆盖所有的场景,将会产生歧义。

分析与思路:

先设置两个变量:

  1. maxPosition ,字符串类型,用以记录最远的坐标,初始值为 "(0,0)"。
  2. maxDistance,整形数字,记录最远的距离,初始值为0。

遍历字符串,在遍历字符串的过程中,找到一个合法坐标后,计算其到总部的距离,设为 tmpDistance,如果 tmpDistance 大于 maxDistance,则把它赋值给 maxDistance,并把把它坐标赋值给 maxPosition。继续遍历字符串,寻找下一个合法坐标,循环判断到总部距离,直到字符串结束。

在计算到总部的距离时,假设坐标为 (x,y) , 则距离为 sqrt( x * x + y * y )。由于此题只关心坐标的相对距离,不需要绝对值,所以可以使用 x * x + y * y 代替其平方根值进行比较,以减少计算量。

代表合法坐标的字符串,在去除首位的小括号后必须满足如下条件:

  1. 中间某个位置(既不是首字母,也不是尾字母)包含字符','。
  2. 通过分隔符 ',' 分开为 2 个字符串,这两个字符串首字母不为 0,且都能解析成正整数。

此算法只需要遍历一次字符串,时间复杂度为 o(n),使用了 2 个额外的原始数据类型变量,空间复杂度为 o(1)。


代码实现

Java代码

java 复制代码
import java.util.Scanner;

/**
 * 最远足迹
 * 
 * @since 2023.09.07
 * @version 0.1
 * @author Frank
 *
 */
public class MaxDistance {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String record = sc.nextLine();

		int i = 0;
		int maxDistance = 0;
		String maxPosition = "(0,0)";
		while (i < record.length()) {
			int leftPT = record.indexOf('(', i);
			int rightPT = record.indexOf(')', i);

			if (leftPT < 0) {
				break;
			}

			String position = record.substring(leftPT + 1, rightPT);
			int tmpDistance = getDistance(position);
			if (tmpDistance > maxDistance) {
				maxDistance = tmpDistance;
				maxPosition = "(" + position + ")";
			}
			i = rightPT + 1;
		}
		System.out.println(maxPosition);
	}

	private static int getDistance(String position) {
		int ret = 0;
		String[] posArr = position.split(",");
		if (posArr == null || posArr.length != 2) {
			return 0;
		}
		for (int i = 0; i < posArr.length; i++) {
			String strPos = posArr[i];
			if (strPos.length() == 0 || strPos.startsWith("0")) {
				return 0;
			}
			try {
				int intPos = Integer.parseInt(strPos);
				ret += (intPos * intPos);
			} catch (NumberFormatException e) {
				return 0;
			}

		}

		return ret;
	}

}

JavaScript代码

javascript 复制代码
const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;

function getDistance( position ) {
    var ret = 0;
    var posArr = position.split(",");
    if (posArr == null || posArr.length != 2) {
        return 0;
    }
    for (var i = 0; i < posArr.length; i++) {
        var strPos = posArr[i];
        if (strPos.length == 0 || strPos.startsWith("0")) {
            return 0;
        }
        var intPos = Number(strPos);
        if( Number.isNaN( intPos) )
        {
            return 0;
        }
        ret += (intPos * intPos);

    }

    return ret;
}

function processInput( line )
{
    var record = line;
    var i = 0;
    var maxDistance = 0;
    var maxPosition = "(0,0)";
    if( !record )
    {
        console.log(maxPosition);
        return;
    }
    while (i < record.length) {
        var leftPT = record.indexOf('(', i);
        var rightPT = record.indexOf(')', i);

        if (leftPT < 0) {
            break;
        }

        var position = record.substring(leftPT + 1, rightPT);
        var tmpDistance = getDistance(position);
        if (tmpDistance > maxDistance) {
            maxDistance = tmpDistance;
            maxPosition = "(" + position + ")";
        }
        i = rightPT + 1;
    }
    console.log(maxPosition);
}

void async function() {
    let input = [];
    while (line = await readline()) {
        processInput( line );
    }

}();

(完)

相关推荐
魔道不误砍柴功1 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_2341 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
pianmian11 小时前
python数据结构基础(7)
数据结构·算法
闲晨1 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
cs_dn_Jie3 小时前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
测开小菜鸟3 小时前
使用python向钉钉群聊发送消息
java·python·钉钉
好奇龙猫3 小时前
【学习AI-相关路程-mnist手写数字分类-win-硬件:windows-自我学习AI-实验步骤-全连接神经网络(BPnetwork)-操作流程(3) 】
人工智能·算法
开心工作室_kaic3 小时前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
有梦想的刺儿4 小时前
webWorker基本用法
前端·javascript·vue.js
P.H. Infinity4 小时前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq