京东笔试真题 - 过道对岗(C++/Py/Java /Js/Go)题解

过道对岗

京东技术岗 9月5号笔试 第二题

题目内容

冷链库房的地坪划成 hhh 行 www 列的格子。货架占住的格子用 # 表示,走得动的过道用 . 表示。夜班要把两根对讲桩立在两块不同 的过道上,让两桩的曼哈顿距离尽量大。格子 (r1,c1)(r_1,c_1)(r1,c1) 与 (r2,c2)(r_2,c_2)(r2,c2) 的曼哈顿距离是 ∣r1−r2∣+∣c1−c2∣|r_1-r_2|+|c_1-c_2|∣r1−r2∣+∣c1−c2∣,按坐标直接算,中间隔着货架也不改这个值。

请给出任意一对能达到最大距离的过道坐标。行号、列号都从 1 开始。保证过道至少有两格。

约束:

  • 1 ≤\le≤ h,wh,wh,w ≤\le≤ 200000
  • 1 ≤\le≤ h×wh\times wh×w ≤\le≤ 200000
  • 每个格子只可能是 .#
  • 过道格子数不少于 2

输入描述

第一行两个整数 hhh、www(1 ≤\le≤ h,wh,wh,w ≤\le≤ 200000),表示行数和列数。

随后 hhh 行,每行一个长度为 www 的字符串,只含 .#

输出描述

一行四个整数 r1r_1r1、c1c_1c1、r2r_2r2、c2c_2c2,表示两根对讲桩所在过道的行号和列号。

若有多种最大方案,输出任意一种即可。

样例1

输入

复制代码
3 4
.#..
#..#
..#.

输出

复制代码
1 1 3 4

说明

过道里 (1,1)(1,1)(1,1) 与 (3,4)(3,4)(3,4) 的曼哈顿距离是 ∣1−3∣+∣1−4∣='5'|1-3|+|1-4|=`5`∣1−3∣+∣1−4∣='5',已经是最大。(1,4)(1,4)(1,4) 与 (3,1)(3,1)(3,1) 距离同样是 5,输出那一组也对。

样例2

输入

复制代码
1 6
.#..#.

输出

复制代码
1 1 1 6

说明

只有一行。最左和最右两块过道距离为 5,这是唯一的最大取法。

样例3

输入

复制代码
4 4
#...
####
####
..##

输出

复制代码
1 4 4 1

说明

(1,4)(1,4)(1,4) 与 (4,1)(4,1)(4,1) 距离为 6。若只拿「行加列」最小和最大的两格 (1,2)(1,2)(1,2) 与 (4,2)(4,2)(4,2),距离只有 3,不是最大。

思路

解题方法:逻辑分析

  1. ∣r1​−r2​∣+∣c1​−c2​∣ 分解之后,最大值求一下几种情况最大值
    1. (r1+c1)−(r2+c2)
    2. (r2+c2)−(r1+c1)
    3. (r1−c1)−(r2−c2)
    4. (r2−c2)−(r1−c1)
  2. 按照上面公式我们只需要找
    • r + c 最大和最小两个过道格, 对应1,2
    • r - c 最大和最小的两个过道格。对应3,4
  3. 最大值为max(max(r + c) - min(r + c), max(r-c) - min(r -c))

python

python 复制代码
import sys


class Point:
    def __init__(self, r, c):
        self.r = r
        self.c = c


def solve(h, w, input_data):
    maxSum = -sys.maxsize
    minSum = sys.maxsize
    maxDiff = -sys.maxsize
    minDiff = sys.maxsize

    maxSumPoint = None
    minSumPoint = None
    maxDiffPoint = None
    minDiffPoint = None

    # 一次只读取一行,因此不需要保存整个网格
    for r in range(1, h + 1):
        s = next(input_data)

        for c in range(1, w + 1):
            if s[c - 1] != '.':
                continue

            sum_val = r + c
            diff = r - c

            # 更新 r + c 最大值
            if sum_val > maxSum:
                maxSum = sum_val
                maxSumPoint = Point(r, c)

            # 更新 r + c 最小值
            if sum_val < minSum:
                minSum = sum_val
                minSumPoint = Point(r, c)

            # 更新 r - c 最大值
            if diff > maxDiff:
                maxDiff = diff
                maxDiffPoint = Point(r, c)

            # 更新 r - c 最小值
            if diff < minDiff:
                minDiff = diff
                minDiffPoint = Point(r, c)

    # r + c 方向的最大曼哈顿距离
    d1 = maxSum - minSum

    # r - c 方向的最大曼哈顿距离
    d2 = maxDiff - minDiff

    if d1 >= d2:
        print(
            minSumPoint.r, minSumPoint.c,
            maxSumPoint.r, maxSumPoint.c
        )
    else:
        print(
            minDiffPoint.r, minDiffPoint.c,
            maxDiffPoint.r, maxDiffPoint.c
        )


def main():
    input_data = iter(sys.stdin.read().split())

    h = int(next(input_data))
    w = int(next(input_data))

    solve(h, w, input_data)


if __name__ == "__main__":
    main()

C++

python 复制代码
#include <bits/stdc++.h>
using namespace std;

struct Point {
    int r, c;
};

void solve(int h, int w) {
    int maxSum = INT_MIN;
    int minSum = INT_MAX;
    int maxDiff = INT_MIN;
    int minDiff = INT_MAX;

    Point maxSumPoint, minSumPoint;
    Point maxDiffPoint, minDiffPoint;

    // 一次只读取一行,因此不需要保存整个网格
    for (int r = 1; r <= h; r++) {
        string s;
        cin >> s;

        for (int c = 1; c <= w; c++) {
            if (s[c - 1] != '.') {
                continue;
            }

            int sum = r + c;
            int diff = r - c;

            // 更新 r + c 最大值
            if (sum > maxSum) {
                maxSum = sum;
                maxSumPoint = {r, c};
            }

            // 更新 r + c 最小值
            if (sum < minSum) {
                minSum = sum;
                minSumPoint = {r, c};
            }

            // 更新 r - c 最大值
            if (diff > maxDiff) {
                maxDiff = diff;
                maxDiffPoint = {r, c};
            }

            // 更新 r - c 最小值
            if (diff < minDiff) {
                minDiff = diff;
                minDiffPoint = {r, c};
            }
        }
    }

    // r + c 方向的最大曼哈顿距离
    int d1 = maxSum - minSum;

    // r - c 方向的最大曼哈顿距离
    int d2 = maxDiff - minDiff;

    if (d1 >= d2) {
        cout << minSumPoint.r << ' ' << minSumPoint.c << ' '
             << maxSumPoint.r << ' ' << maxSumPoint.c << '\n';
    } else {
        cout << minDiffPoint.r << ' ' << minDiffPoint.c << ' '
             << maxDiffPoint.r << ' ' << maxDiffPoint.c << '\n';
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int h, w;
    cin >> h >> w;

    solve(h, w);

    return 0;
}

Java

java 复制代码
import java.io.*;
import java.util.*;

public class Main {
    static class Point {
        int r, c;

        Point(int r, int c) {
            this.r = r;
            this.c = c;
        }
    }

    static void solve(int h, int w, Scanner sc) {
        int maxSum = Integer.MIN_VALUE;
        int minSum = Integer.MAX_VALUE;
        int maxDiff = Integer.MIN_VALUE;
        int minDiff = Integer.MAX_VALUE;

        Point maxSumPoint = null;
        Point minSumPoint = null;
        Point maxDiffPoint = null;
        Point minDiffPoint = null;

        // 一次只读取一行,因此不需要保存整个网格
        for (int r = 1; r <= h; r++) {
            String s = sc.next();

            for (int c = 1; c <= w; c++) {
                if (s.charAt(c - 1) != '.') {
                    continue;
                }

                int sum = r + c;
                int diff = r - c;

                // 更新 r + c 最大值
                if (sum > maxSum) {
                    maxSum = sum;
                    maxSumPoint = new Point(r, c);
                }

                // 更新 r + c 最小值
                if (sum < minSum) {
                    minSum = sum;
                    minSumPoint = new Point(r, c);
                }

                // 更新 r - c 最大值
                if (diff > maxDiff) {
                    maxDiff = diff;
                    maxDiffPoint = new Point(r, c);
                }

                // 更新 r - c 最小值
                if (diff < minDiff) {
                    minDiff = diff;
                    minDiffPoint = new Point(r, c);
                }
            }
        }

        // r + c 方向的最大曼哈顿距离
        int d1 = maxSum - minSum;

        // r - c 方向的最大曼哈顿距离
        int d2 = maxDiff - minDiff;

        if (d1 >= d2) {
            System.out.println(
                minSumPoint.r + " " + minSumPoint.c + " " +
                maxSumPoint.r + " " + maxSumPoint.c
            );
        } else {
            System.out.println(
                minDiffPoint.r + " " + minDiffPoint.c + " " +
                maxDiffPoint.r + " " + maxDiffPoint.c
            );
        }
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int h = sc.nextInt();
        int w = sc.nextInt();

        solve(h, w, sc);
    }
}

javascript

js 复制代码
const readline = require('readline');

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

const lines = [];

rl.on('line', line => {
    lines.push(line.trim());
});

rl.on('close', () => {
    let index = 0;

    const [h, w] = lines[index++].split(/\s+/).map(Number);

    solve(h, w);
});

class Point {
    constructor(r, c) {
        this.r = r;
        this.c = c;
    }
}

function solve(h, w) {
    let maxSum = -Infinity;
    let minSum = Infinity;
    let maxDiff = -Infinity;
    let minDiff = Infinity;

    let maxSumPoint = null;
    let minSumPoint = null;
    let maxDiffPoint = null;
    let minDiffPoint = null;

    // 一次只读取一行,因此不需要保存整个网格
    for (let r = 1; r <= h; r++) {
        const s = lines[r];

        for (let c = 1; c <= w; c++) {
            if (s[c - 1] !== '.') {
                continue;
            }

            const sum = r + c;
            const diff = r - c;

            // 更新 r + c 最大值
            if (sum > maxSum) {
                maxSum = sum;
                maxSumPoint = new Point(r, c);
            }

            // 更新 r + c 最小值
            if (sum < minSum) {
                minSum = sum;
                minSumPoint = new Point(r, c);
            }

            // 更新 r - c 最大值
            if (diff > maxDiff) {
                maxDiff = diff;
                maxDiffPoint = new Point(r, c);
            }

            // 更新 r - c 最小值
            if (diff < minDiff) {
                minDiff = diff;
                minDiffPoint = new Point(r, c);
            }
        }
    }

    // r + c 方向的最大曼哈顿距离
    const d1 = maxSum - minSum;

    // r - c 方向的最大曼哈顿距离
    const d2 = maxDiff - minDiff;

    if (d1 >= d2) {
        console.log(
            minSumPoint.r + ' ' + minSumPoint.c + ' ' +
            maxSumPoint.r + ' ' + maxSumPoint.c
        );
    } else {
        console.log(
            minDiffPoint.r + ' ' + minDiffPoint.c + ' ' +
            maxDiffPoint.r + ' ' + maxDiffPoint.c
        );
    }
}

Go

go 复制代码
package main

import (
	"bufio"
	"fmt"
	"os"
)

func solve(h, w int, in *bufio.Reader) {
	maxSum := -int(^uint(0)>>1) - 1
	minSum := int(^uint(0) >> 1)
	maxDiff := -int(^uint(0)>>1) - 1
	minDiff := int(^uint(0) >> 1)

	var maxSumR, maxSumC int
	var minSumR, minSumC int
	var maxDiffR, maxDiffC int
	var minDiffR, minDiffC int

	// 一次只读取一行,因此不需要保存整个网格
	for r := 1; r <= h; r++ {
		var s string
		fmt.Fscan(in, &s)

		for c := 1; c <= w; c++ {
			if s[c-1] != '.' {
				continue
			}

			sum := r + c
			diff := r - c

			// 更新 r + c 最大值
			if sum > maxSum {
				maxSum = sum
				maxSumR = r
				maxSumC = c
			}

			// 更新 r + c 最小值
			if sum < minSum {
				minSum = sum
				minSumR = r
				minSumC = c
			}

			// 更新 r - c 最大值
			if diff > maxDiff {
				maxDiff = diff
				maxDiffR = r
				maxDiffC = c
			}

			// 更新 r - c 最小值
			if diff < minDiff {
				minDiff = diff
				minDiffR = r
				minDiffC = c
			}
		}
	}

	// r + c 方向的最大曼哈顿距离
	d1 := maxSum - minSum

	// r - c 方向的最大曼哈顿距离
	d2 := maxDiff - minDiff

	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	if d1 >= d2 {
		fmt.Fprintln(out,
			minSumR, minSumC,
			maxSumR, maxSumC)
	} else {
		fmt.Fprintln(out,
			minDiffR, minDiffC,
			maxDiffR, maxDiffC)
	}
}

func main() {
	in := bufio.NewReader(os.Stdin)

	var h, w int
	fmt.Fscan(in, &h, &w)

	solve(h, w, in)
}
相关推荐
电商API_180079052471 天前
电商平台数据分析实战_帖子
开发语言·爬虫·python·数据采集·京东
deepseek236 天前
京东 JoyAI 物理基座模型 PhysBrain 1.5 发布拆解:8B 参数如何通过人类学习范式拿下开源第一,媲美 GPT-6 Astra
机器人·具身智能·ai agent·京东·物理智能
无限码力14 天前
2026京东笔试真题【第几条明暗交错子序列】多语言题解
京东·京东笔试真题·京东笔试·京东笔试真题题解·京东提前批笔试真题·京东笔试题解
xiaofeicaiyan17 天前
从财报看外卖:美团守壁垒、阿里养生态、京东换流量
美团·阿里·京东
无限码力1 个月前
京东笔试真题 - 以弱胜强的秘密(C++/Py/Java /Js/Go)
京东·京东笔试真题·京东机试·京东最新笔试真题·京东技术岗笔试·京东最新笔试真题题解
无限码力1 个月前
京东笔试真题 - 失落的宝石(C++/Py/Java /Js/Go)
京东·京东笔试真题·京东技术岗笔试真题·京东笔试·京东机试
电商API_180079052471 个月前
京东商品详情API技术解析:数据结构、调用实践与系统集成方案
python·api·跨境电商·京东·商品详情
加油20196 个月前
京东人事管理8项规定
管理·京东·8项规定
Cyril_KI2 年前
京东 2025届秋招 自然语言处理
自然语言处理·京东·面试经验·2025届校招