首页 > 试题广场 >

窗口点击模拟

[编程题]窗口点击模拟
  • 热度指数:1328 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
本题需要让你模拟一下在Windows系统里窗口和鼠标点击的操作,具体如下:
1.屏幕分辨率为3840*2160,左上角坐标为(0, 0), 右下角坐标为(3839, 2159)
2.窗口是一个矩形的形状,由左上角坐标(X, Y),和宽高(W, H),四个数字来定位。左上角坐标为(X, Y)、右下角坐标为(X+W, Y+H),其中左上角坐标一定会在屏幕范围内,其他一些部分可能会超过屏幕范围。
3.窗口的点击和遮挡规则同Windows,但是不考虑关闭窗口、最大化、最小化和强制置顶的情况。即
    3.1 如果发生重叠的话,后面打开的窗口会显示在前面打开的窗口上面
    3.2 当鼠标发生一次点击的时候,需要判断点击到了哪个窗口,如果同个坐标有多个窗口,算点击到最上层的那个
    3.3 当一个窗口被点击的时候,会浮动到最上层


输入描述:
每个测试输入包含1个测试用例
第一行为2个整数N, M。其中N表示打开的窗口数目,M表示鼠标点击的数目。其中0<N,M<1000
接下来N行,每一行四个整数 Xi Yi Wi Hi,分别表示第i个窗口(窗口Id为i,从1开始计数)的左上角坐标以及宽高,初始时窗口是按输入的顺序依次打开。其中 0<=Xi<3840, 0<=Yi<2160, 0<Wi<3840, 0<Hi<2160
再接下来有M行,每一行两个整数 Xj Yj,分别表示接下来发生的鼠标点击坐标。其中 0 <=Xj<3840, 0<=Yj<2160


输出描述:
对于每次鼠标点击,输出本次点击到的窗口Id。如果没有点击到窗口,输出-1
示例1

输入

2 4
100 100 100 100
10 10 150 150
105 105
180 180
105 105
1 1

输出

2
1
1
-1

构造窗口ID列表,点击后调整ID列表顺序

import sys
N, M = map(int, sys.stdin.readline().split())
topWindowIndex = [N-i for i in list(range(0, N+1))]
Xs = [[0, 0, 0, 0] for i in range(N+1)]
Xs[0] = [0, 0, 3840, 2160]
for i in range(1, N+1):
    Xi, Yi, Wi, Hi = map(int, sys.stdin.readline().split())
    Xs[i] = [Xi, Yi, Wi, Hi]
for j in range(M):
    Xj, Yj = map(int, sys.stdin.readline().split())
    # in region?
    index, ind = 0, 0
    for ind, i in enumerate(topWindowIndex):
        dx, dy = Xj-Xs[i][0], Yj-Xs[i][1]
        if dx>=0 and dy>=0 and dx<=Xs[i][2] and dy<=Xs[i][3]:
            index = i
            break
    # swap index
    if index==0:
        print(-1)
    else:
        print(index)
        # for i in range(ind-1, -1, -1):
        #     topWindowIndex[i+1] = topWindowIndex[i]
        # topWindowIndex[0] = index
        topWindowIndex.pop(ind)
        topWindowIndex.insert(0, index)




编辑于 2025-04-11 22:52:50 回复(0)
# 最简单的一题了,依然保留了默认的输入结构。
# 思路是将窗口按照输入顺序进行编号,并将窗口的前后顺序看作一个栈。
# 先创建的窗口在底部,后创建的在栈口。
# 针对每一次点击都从栈口开始依次对每个窗口进行判定。
# 被点击到的窗口从栈中取出并放置在栈口,跳出本次点击的循环,开始下一次点击的遍历。
# 如果遍历完所有窗口都没有跳出本次点击的循环,则说明没有点击到任何窗口。

import sys

lines = []

try:
    while True:    # 获取所有输入
        line = sys.stdin.readline().strip()
        if line == '':
            break
        lines.append(line.split())
    N_windows,N_check = int(lines[0][0]),int(lines[0][1])
    windows = lines[1:N_windows+1]
    windows_idx = [i for i in range(N_windows)]    # 将窗口的顺序视为一个栈,越接近栈口越优先点击
    for check in lines[N_windows+1:]:    # 每个鼠标点击都对所有窗口判定一次直到判定点击到窗口
        new_idx = reversed(windows_idx)    # 列表遍历顺序与栈相反,需要先将列表反转
        for i in new_idx:
            Xi,Yi,Wi,Hi = int(windows[i][0]),int(windows[i][1]),int(windows[i][2]),int(windows[i][3])
            if Xi<=int(check[0])<=Xi+Wi and Yi<=int(check[1])<=Yi+Hi:    # 是否在当前窗口内
                print(i+1)
                windows_idx.remove(i)        # 将鼠标点击到的窗口放置到栈口
                windows_idx.append(i)
                break
        else:    # 不在任何窗口内
            print(-1)
            continue
except:
    pass

编辑于 2023-04-20 15:23:52 回复(0)