【备战秋招】每日一题:2023.05.17-华为(第一题)-方格音游

为了更好的阅读体检,可以查看我的算法学习博客
在线评测链接:P1293

题目描述

塔子哥最近沉迷于设计一个二维平面音游。

在我们所给的例子里,假设有 24 24 24个方块,分为水平8个和垂直3个(如下表格所示)

当玩家点击一个亮起的方块时,它周围的所有方块都会高亮。为了实现这个互动功能,塔子哥提出了一个方块组的概念:一个方块的方块组是指在上下左右方向上紧挨着的所有方块和它自己。而且垂直方向上的方块是首尾相连的,但水平方向上的方块是首尾不连的。

比如,在 48 48 48个方块中,方块 0 0 0的方块组是“ 16 16 16 8 8 8 1 1 1 0 0 0”,方块 10 10 10的方块组是“ 2 2 2 9 9 9 18 18 18 11 11 11 10 10 10”,方块 23 23 23的方块组是“ 15 15 15 22 22 22 7 7 7 23 23 23”。如下图所示,为了方便理解,我们把最后一行方块复制一份到第一行,表示上下相连:

16 16 16 17 17 17 18 18 18 19 19 19 20 20 20 21 21 21 22 22 22 23 23 23
0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 7 7 7
8 8 8 9 9 9 10 10 10 11 11 11 12 12 12 13 13 13 14 14 14 15 15 15
16 16 16 17 17 17 18 18 18 19 19 19 20 20 20 21 21 21 22 22 22 23 23 23

塔子哥想要当玩家点击某个方块时,这个方块的整个方块组都会亮起。为了实现这个互动功能,他想让你设计一个程序,它能实时得到某个方块的方块组。

输入描述

第一行输入为 3 3 3个正整数 H H H , V V V ( 1 ≤ H , V ≤ 256 ) (1\leq H,V \leq 256) (1H,V256) M M M ( 1 ≤ M < H × V ) (1 \leq M < H\times V ) (1M<H×V), H H H V V V 为方块盘的水平个数和垂直个数;

接下来 M M M 行,每一行输入一个方块的 I D ID ID ,方格 I D ID ID 0 0 0开始,不超过 H × V − 1 H\times V - 1 H×V1 如:

8 3 1
12

输出描述

输出对应的方格组,方格组内 I D ID ID 以空格分隔, I D ID ID从上方起始,逆时针排列,输入的方格 I D ID ID 放最后,如上例子对应的输出结果为:
4 4 4 11 11 11 20 20 20 13 13 13 12 12 12

样例

输入

12 4 1
21

输出

9 20 33 22 21

样例2

输入

16 4 2
0
21

输出

48 16 1 0
5 20 37 22 21

思路

是否构图

首先,我们发现只要给定 n n n m m m,那么一整张图就会被固定。因此,我们不需要尝试去构造整个图。

如何查询

对于每次对于给定 I D ID ID(数值记为 x x x),询问方块组,具体做法如下:

  • 我们发现垂直方向是首尾相连的,因此,我们可以利用 x − n x - n xn x + n x + n x+n分别表示 I D ID ID上方数值和 I D ID ID下方数值。然而,我们发现如果 x − n x-n xn小于0时,我们需要令 x − n x-n xn加上 n ∗ m n*m nm,如果 x + n x+n x+n大于等于 n ∗ m n*m nm,我们需要令 x + n x+n x+n减去 n ∗ m n*m nm。因此,为了简化操作,我们可以对于这两个数值都加上 n ∗ m n*m nm,再取余 n ∗ m n*m nm
  • 我们发现水平方向不是首位相连的,因此,我们只要判断 x − 1 x-1 x1 x + 1 x+1 x+1存不存在即可。

类似题目推荐

代码

CPP

#include <bits/stdc++.h>
using namespace std;
int n, m, k;
int main(){
    cin >> n >> m >> k;//输入
    for(int i = 0; i < k; i++){
        int x;
        cin >> x;//输入询问ID
        cout << (x - n + n * m) % (n * m) << " ";//输出ID上方的数字
        if(x % n != 0)cout << x - 1 << " ";//输出ID左方的数字
        cout << (x + n + n * m) % (n * m) << " ";//输出ID下方的数字
        if((x + 1) % n != 0)cout << x + 1 << " ";//输出ID右方的数字
        cout << x << endl; //输出ID
    }
}

python

n, m, k = map(int, input().split())#输入

for _ in range(k):
    x = int(input())#输入询问ID
    print((x - n + n * m) % (n * m), end=" ")#输出ID上方的数字
    if x % n != 1:
        print(x - 1, end=" ")#输出ID左方的数字
    print((x + n + n * m) % (n * m), end=" ")#输出ID下方的数字
    if (x + 1) % n != 0:
        print(x + 1, end=" ")#输出ID右方的数字
    print(x)#输出ID

Java

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();//输入
        int m = scanner.nextInt();
        int k = scanner.nextInt();

        for (int i = 0; i < k; i++) {
            int x = scanner.nextInt();//输入询问ID
            System.out.print((x - n + n * m) % (n * m) + " ");//输出ID上方的数字
            if (x % n != 1) {
                System.out.print(x - 1 + " ");//输出ID左方的数字
            }
            System.out.print((x + n + n * m) % (n * m) + " ");//输出ID下方的数字
            if ((x + 1) % n != 0) {
                System.out.print(x + 1 + " ");//输出ID右方的数字
            }
            System.out.println(x);//输出ID
        }
    }
}

Go

package main

import "fmt"

func main() {
    var n, m, k int
    fmt.Scan(&n, &m, &k)//输入

    for i := 0; i < k; i++ {
        var x int
        fmt.Scan(&x)//输入询问ID
        fmt.Printf("%d ", (x-n+n*m)%(n*m))//输出ID上方的数字
        if x%n != 1 {
            fmt.Printf("%d ", x-1)//输出ID左方的数字
        }
        fmt.Printf("%d ", (x+n+n*m)%(n*m))//输出ID下方的数字
        if (x+1)%n != 0 {
            fmt.Printf("%d ", x+1)//输出ID右方的数字
        }
        fmt.Println(x)//输出ID
    }
}

Js

const readline = require('readline');

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

rl.on('line', (line) => {
    const [n, m, k] = line.trim().split(' ').map(Number);//输入
    for (let i = 0; i < k; i++) {
        rl.on('line', (x) => {
            x = Number(x);//输入询问ID
            process.stdout.write(((x - n + n * m) % (n * m)) + ' ');//输出ID上方的数字
            if (x % n !== 1) {
                process.stdout.write((x - 1) + ' ');//输出ID左方的数字
            }
            process.stdout.write(((x + n + n * m) % (n * m)) + ' ');//输出ID下方的数字
            if ((x + 1) % n !== 0) {
                process.stdout.write((x + 1) + ' ');//输出ID右方的数字
            }
            console.log(x);//输出ID
        });
    }
});


题目内容均收集自互联网,如如若此项内容侵犯了原著者的合法权益,可联系我: (CSDN网站注册用户名: 塔子哥学算法) 进行删除。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

塔子哥学算法

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值