题目描述

在一个窗口系统中,有N个窗口,每个窗口有编号(按题目给出的顺序)。当点击某个位置时,被点击的最顶层窗口会被激活并移到最前面。

给定多个点击位置,需要输出每个点击位置点击的是哪个窗口(如果点击位置没有窗口则输出”IGNORED”)。

算法思路

使用数组模拟窗口的层叠顺序:

  1. 用数组记录当前窗口的层序(下标越小越靠前)
  2. 对于每次点击,从后往前遍历窗口(因为后面的窗口在前面)
  3. 找到第一个包含点击位置的窗口后,将其移到最前面
  4. 输出结果

关键:点击后该窗口需要激活(移到最前面),其他窗口相对顺序不变。

代码实现

#include <bits/stdc++.h>
using namespace std;
 
struct Window {
    int x1, y1, x2, y2;
};
 
int main(){
    ios::sync_with_stdio(false);cin.tie(nullptr);
    int n, m;
    cin >> n >> m;
    vector<Window> w(n);
    for(int i = 0; i < n; i++){
        cin >> w[i].x1 >> w[i].y1 >> w[i].x2 >> w[i].y2;
    }
    vector<int> order(n);
    for(int i = 0; i < n; i++) order[i] = i;
    
    for(int i = 0; i < m; i++){
        int x, y;
        cin >> x >> y;
        int clicked = -1;
        // 从最前面的窗口开始检查(即倒序遍历)
        for(int j = n - 1; j >= 0; j--){
            int idx = order[j];
            if(x >= w[idx].x1 && x <= w[idx].x2 && y >= w[idx].y1 && y <= w[idx].y2){
                clicked = idx;
                // 将该窗口移到最前面
                for(int k = j; k < n - 1; k++){
                    order[k] = order[k + 1];
                }
                order[n - 1] = idx;
                break;
            }
        }
        if(clicked == -1) cout << "IGNORED" << endl;
        else cout << clicked + 1 << endl;
    }
    return 0;
}

关键点

  • 窗口层序用数组模拟,order[i]表示第i层窗口的索引
  • 点击时从最前面(order末尾)开始检查
  • 命中的窗口需要移动到最前面,保持其他窗口相对顺序
  • 注意坐标边界条件的包含关系

参考

  • CCF-CSP认证