清理垃圾 set/栈/模拟

解题思路分析:

  1. 数据结构选择

    • 使用两个数组vishvisl分别记录每行和每列的垃圾数量

    • 使用两个栈数组gb分别存储每行和每列的垃圾位置信息

    • 这种设计可以高效地进行查询和删除操作

  2. 处理流程

    • 初始化阶段:读取所有垃圾位置,统计每行每列的垃圾数量,并存储位置信息

    • 查询处理阶段

      • 对于行查询(类型1):输出该行垃圾数后,清除该行所有垃圾,并同步更新对应列的计数

      • 对于列查询(类型2):输出该列垃圾数后,清除该列所有垃圾,并同步更新对应行的计数

  3. 关键优化点

    • 使用栈存储位置信息,可以按照后进先出的顺序处理垃圾清除

    • 每次清除操作都会同步更新行列计数,确保后续查询的正确性

    • max(0, count)确保即使重复查询已清除的行列也不会输出负数

  4. 复杂度分析

    • 时间复杂度:O(N + Q),每个垃圾和查询都只被处理一次

    • 空间复杂度:O(N),与垃圾数量成正比

  5. 注意事项

    • 全局数组的大小需要根据题目约束设置足够大

    • 使用栈结构可以高效处理清除操作,但要注意栈的操作顺序

    • 输入数据量较大,使用scanf提高读取效率

这个解法通过合理的数据结构设计,实现了对大规模数据的高效处理,能够满足题目要求的性能约束。

 
 
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;  // 定义最大可能的数据范围

// 定义全局变量:
int vish[N], visl[N];    // vish[x]记录第x行的垃圾数量,visl[y]记录第y列的垃圾数量
stack<int> g[N], b[N];   // g[x]存储第x行的所有垃圾列号,b[y]存储第y列的所有垃圾行号
int n, m, k;             // n行,m列,k个垃圾

int main() {
    // 输入网格基本信息和垃圾位置
    cin >> n >> m >> k;
    for(int i = 1; i <= k; i++) {
        int x, y; 
        scanf("%d%d", &x, &y);  // 读取每个垃圾的位置
        
        // 更新行和列的垃圾计数
        vish[x]++;     // 第x行垃圾数+1
        visl[y]++;     // 第y列垃圾数+1
        
        // 将垃圾位置存入对应的行和列的栈中
        g[x].push(y);  // 第x行的垃圾所在列
        b[y].push(x);  // 第y列的垃圾所在行
    }
    
    // 处理查询
    int q; cin >> q;   // 查询数量
    while(q--) {
        int op, t;
        scanf("%d%d", &op, &t);  // 读取查询类型和参数
        
        // 类型1查询:处理行
        if(op == 1) {
            // 输出该行的垃圾数量(确保非负)
            printf("%d\n", max(0, vish[t]));
            
            // 清除该行的垃圾计数
            vish[t] = 0;
            
            // 遍历该行的所有垃圾,清除对应列的计数
            while(g[t].size()) {
                int p = g[t].top();  // 获取该行的一个垃圾所在列
                g[t].pop();          // 从栈中移除
                visl[p]--;           // 对应列的垃圾数-1
            }
        }
        
        // 类型2查询:处理列
        if(op == 2) {
            // 输出该列的垃圾数量(确保非负)
            printf("%d\n", max(0, visl[t]));
            
            // 清除该列的垃圾计数
            visl[t] = 0;
            
            // 遍历该列的所有垃圾,清除对应行的计数
            while(b[t].size()) {
                int p = b[t].top();  // 获取该列的一个垃圾所在行
                b[t].pop();          // 从栈中移除
                vish[p]--;           // 对应行的垃圾数-1
            }
        }
    }
    return 0;
}

 

 
posted @ 2025-05-22 19:01  CRt0729  阅读(15)  评论(0)    收藏  举报