同行列对角线的格

GitHub跳转原题关系图返回列表

用行号、列号、行减列、行加列四个不变量刻画四条线,再用 max/min 裁出对角线在棋盘内的行号区间,按指定方向枚举输出。

OJ: roj

题目 ID: 1120

难度:入门

标签:入门输入输出

创建: 2026-09-29 19:38

更新: 2026-10-05 02:31

题目描述

给定 N×NN\times N 棋盘(行列从 1 开始)上的格子 (i,j)(i,j),输出与它在同一行、同一列、同一主对角线、同一副对角线上的所有格子坐标。同行从左到右、同列从上到下、主对角线从左上到右下、副对角线从左下到右上;每个坐标格式为 (x,y),相邻坐标间用一个空格隔开。1≤N≤101\le N\le 10。

思路

行固定 ii、列固定 jj 即可直接枚举;主对角线满足 r−c=i−jr-c=i-j,副对角线满足 r+c=i+jr+c=i+j,再用 max⁡/min⁡\max/\min 与棋盘边界 [1,N][1,N] 取交得到对角线的行号区间。四条线统一格式化输出,复杂度 O(N)O(N)。

参考代码

Python 版:

python
#!/usr/bin/env python3
# Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
# rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
# rainboy的学习导航网站: https://idx.roj.ac.cn
# create_at: 2026-09-29 19:38
# update_at: 2026-09-29 19:38

import sys


def solve() -> None:
    n, i, j = map(int, sys.stdin.read().split())

    same_row = [(i, c) for c in range(1, n + 1)]                    # 同一行:列从左到右
    same_col = [(r, j) for r in range(1, n + 1)]                    # 同一列:行从上到下

    diff = i - j  # 主对角线不变量:行号 - 列号
    # 行从左上角 max(1,1+diff) 扫到右下角 min(n,n+diff),列随之确定
    main_diag = [(r, r - diff) for r in range(max(1, 1 + diff), min(n, n + diff) + 1)]

    total = i + j  # 副对角线不变量:行号 + 列号
    # 行从 min(n, total-1)(左下角)倒着扫到 max(1, total-n)(右上角)
    anti_diag = [(r, total - r) for r in range(min(n, total - 1), max(1, total - n) - 1, -1)]

    out = '\n'.join(
        ' '.join(f'({x},{y})' for x, y in line)
        for line in (same_row, same_col, main_diag, anti_diag)
    )
    print(out)


if __name__ == "__main__":
    solve()

C++ 版(同一算法):

cpp
/**
 * Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
 * rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
 * rainboy的学习导航网站: https://idx.roj.ac.cn
 * create_at: 2026-09-29 19:38
 * update_at: 2026-10-05 02:31
 */
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

typedef long long ll;

ll n, i, j;

// 输出同一行、列或对角线上的所有坐标,格式为 (x,y),相邻坐标间一个空格
void print_line(const vector<pair<ll, ll> > &cells) {
    for (ll k = 0; k < (ll)cells.size(); k++) {
        if (k > 0) cout << ' ';
        cout << '(' << cells[k].first << ',' << cells[k].second << ')';
    }
    cout << '\n';
}

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

    cin >> n >> i >> j;

    vector<pair<ll, ll> > row, col, diag1, diag2;

    // 同行:第 i 行,列号从左到右 1..n
    for (ll c = 1; c <= n; c++) row.push_back(make_pair(i, c));
    // 同列:第 j 列,行号从上到下 1..n
    for (ll r = 1; r <= n; r++) col.push_back(make_pair(r, j));

    // 主对角线(左上到右下):行号 - 列号 = i - j
    ll d = i - j;
    ll r1 = max(1LL, 1 + d);
    ll r2 = min(n, n + d);
    for (ll r = r1; r <= r2; r++) diag1.push_back(make_pair(r, r - d));

    // 副对角线(左下到右上):行号 + 列号 = i + j
    ll s = i + j;
    ll r3 = max(1LL, s - n);
    ll r4 = min(n, s - 1);
    for (ll r = r4; r >= r3; r--) diag2.push_back(make_pair(r, s - r));

    print_line(row);
    print_line(col);
    print_line(diag1);
    print_line(diag2);

    return 0;
}