202303 CSP认证 | LDAP

LDAP
好好好,难度直线上升,是一道又有了字符串处理味道的第三题
第一把写官网40分,acwing TLE且只通过了一道数据…本文是自己这题奋斗过程 的一个记录

先贴个40分的代码:
在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;   // key and value pair
int n;

unordered_map<int, unordered_map<string, string> > user;  //每个用户对应一个key and value的映射表
unordered_map<string, unordered_set<int> > key_user;  //i作为key, 表示哪些用户具有属性i

//处理一个基本表达式,检查基本表达式与dn的用户是否匹配
set<int> base_expr(string expr)
{
    int i = 0;
    while(expr[i] != ':' && expr[i] != '~') i ++;
    string arr = expr.substr(0, i);
    string value = expr.substr(i + 1, expr.size() - i - 1);

    set<int> res;

    unordered_set<int> users = key_user[arr];
    if(expr[i] == ':'){
        for(auto x : users){   //遍历每一个用户
            if(user[x][arr] == value){
                res.insert(x);
            }
        }
    }else{
        for(auto x : users){
            if(user[x][arr] != value){
                res.insert(x);
            }
        }
    }

    return res;
}

//处理一个常规的表达式
set<int> handle(string expr)
{
    set<int> ans;

    //括号要成对取出
    if(expr[0] == '&' || expr[0] == '|'){
        stack<char> s; int i = 2;
        set<int> res1, res2;

        s.push('(');
        int cnt = 1;
        while(!s.empty()){
            while(expr[i] != '(' && expr[i] != ')') i ++;
            if(expr[i] == '(') { s.push('('); cnt ++; }  //入栈并进行计数
            else if(expr[i] == ')') s.pop(); //弹出一个栈顶的
            i ++;
        }
        //此时第一个括号提取完毕
        string expr1 = expr.substr(2, i - 3);
        string expr2 = expr.substr(i + 1, expr.size() - i - 2);
        //cout << "两个表达式分别为:\n" << expr1 <<"\n" << expr2 <<"\n";

        if(cnt == 1){   //此时是一个简单表达式
            res1 = base_expr(expr1);
            res2 = base_expr(expr2);
        }
        else{
            res1 = handle(expr1);
            res2 = handle(expr2);
        }


        if(expr[0] == '&'){  //取两个集合的交集
            for(auto x : res1){   //遍历一个集合就可以了
                if(res2.count(x)) ans.insert(x);
            }

        }else{   //取两个集合的并集
            for(auto x : res1) ans.insert(x);
            for(auto x : res2) ans.insert(x);
        }

    }

    else { //若要处理的输入就是一个基本表达式
        ans = base_expr(expr);
    }

    return ans;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> n;
    for(int i = 0;i < n;i ++){
        int dn, x;
        string arr, val;
        cin >> dn >> x;
        while(x --){
            cin >> arr >> val;
            key_user[arr].insert(dn);  //dn具有属性arr
            user[dn][arr] = val;  //dn具有属性arr,且value = val
        }
    }
    int m; cin >> m;
    string line;
    while(m --){
        cin >> line;
        set<int> ans = handle(line);
        for(auto x : ans){
            cout << x <<' ';
        }
        cout << "\n";
    }
    return 0;
}

秉持着自己的逻辑应该没错但是官网是40分错误的判断,我找了几分代码比对着修改了一下,找到了一个逻辑错误。

handle函数中我统计了一个cnt用于控制当括号里面的是基础表达式的时候就直接调用base_expr函数,问题就出在这里。
· 第一个问题:我只统计了第一个括号的层数,我默认这两个括号的层级是一样的。这样会导致错误,也就是当前一个括号里是基本表达式而第二个括号里面并不是的时候,此时base_expr并不能解决这样的表达式
· 第二个问题:这里也不算会直接导致错误的原因。在handle函数中,如果发现不是一个逻辑表达式的话,其实有调用base_expr函数的。因此不用重复写,直接一直迭代向下调用handle函数即可。

修改后代码运行超时,逻辑问题变优化问题了,先放个70分的代码(代码几乎没变,就是handle函数体内部改变)
在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;   // key and value pair
int n;

unordered_map<int, unordered_map<string, string> > user;  //每个用户对应一个key and value的映射表
unordered_map<string, unordered_set<int> > key_user;  //i作为key, 表示哪些用户具有属性i

//处理一个基本表达式,检查基本表达式与dn的用户是否匹配
set<int> base_expr(string expr)
{
    int i = 0;
    while(expr[i] != ':' && expr[i] != '~') i ++;
    string arr = expr.substr(0, i);
    string value = expr.substr(i + 1, expr.size() - i - 1);

    set<int> res;

    unordered_set<int> users = key_user[arr];
    if(expr[i] == ':'){
        for(auto x : users){   //遍历每一个用户
            if(user[x][arr] == value){
                res.insert(x);
            }
        }
    }else{
        for(auto x : users){
            if(user[x][arr] != value){
                res.insert(x);
            }
        }
    }

    return res;
}

//处理一个常规的表达式
set<int> handle(string expr)
{
    set<int> ans;

    //括号要成对取出
    if(expr[0] == '&' || expr[0] == '|'){
        stack<char> s; int i = 2;
        set<int> res1, res2;

        s.push('(');
        while(!s.empty()){
            while(expr[i] != '(' && expr[i] != ')') i ++;
            if(expr[i] == '(')  s.push('(');    //入栈并进行计数
            else if(expr[i] == ')') s.pop(); //弹出一个栈顶的
            i ++;
        }
        //此时第一个括号提取完毕
        string expr1 = expr.substr(2, i - 3);
        string expr2 = expr.substr(i + 1, expr.size() - i - 2);
        //cout << "两个表达式分别为:\n" << expr1 <<"\n" << expr2 <<"\n";

        res1 = handle(expr1);
        res2 = handle(expr2);

        if(expr[0] == '&'){  //取两个集合的交集
            for(auto x : res1){   //遍历一个集合就可以了
                if(res2.count(x)) ans.insert(x);
            }

        }else{   //取两个集合的并集
            for(auto x : res1) ans.insert(x);
            for(auto x : res2) ans.insert(x);
        }

    }

    else { //若要处理的输入就是一个基本表达式
        ans = base_expr(expr);
    }

    return ans;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> n;
    for(int i = 0;i < n;i ++){
        int dn, x;
        string arr, val;
        cin >> dn >> x;
        while(x --){
            cin >> arr >> val;
            key_user[arr].insert(dn);  //dn具有属性arr
            user[dn][arr] = val;  //dn具有属性arr,且value = val
        }
    }
    int m; cin >> m;
    string line;
    while(m --){
        cin >> line;
        set<int> ans = handle(line);
        for(auto x : ans){
            cout << x <<' ';
        }
        cout << "\n";
    }
    return 0;
}

明天我来看看满分要怎么优化!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/467050.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络:性能指标

计算机网络&#xff1a;性能指标 速率带宽吞吐量时延时延带宽积往返时间利用率丢包率 本博客介绍计算机网络的性能指标&#xff0c;我们可以从不同的方面来度量计算机网络的性能。常用的计算机网络性能指标有以下 8 个&#xff0c;他们是&#xff1a;速率、带宽、吞吐量、时延、…

Android弹出通知

发现把Android通知渠道的重要性设置为最高时&#xff0c;当发送通知时&#xff0c;通知能直接弹出来显示&#xff0c;以前一直搞不明白为什么别的app的通知可以弹出来&#xff0c;我的不行&#xff0c;搞了半天原来是这个属性在作怪&#xff0c;示例如下&#xff1a; class Ma…

Flink源码解析(1)TM启动

网络传输模型 首先在看之前,回顾一下akka模型: Flink通讯模型—Akka与Actor模型-CSDN博客 注:ActorRef就是actor的引用,封装好了actor 下面是jm和tm在通讯上的概念图: RpcGateway 不理解网关的作用,可以先移步看这里:网关_百度百科 (baidu.com) 用于定义RPC协议,是…

CMake学习(上)

1. CMake概述 CMake 是一个项目构建工具&#xff0c;并且是跨平台的。关于项目构建我们所熟知的还有Makefile&#xff08;通过 make 命令进行项目的构建&#xff09;&#xff0c;大多是IDE软件都集成了make&#xff0c;比如&#xff1a;VS 的 nmake、linux 下的 GNU make、Qt …

论文解读之Attention-based Deep Multiple Instance Learning

前言 多实例学习是由监督学习演变而来的&#xff0c;我们都知道&#xff0c;监督学习在训练的时候是一个实例&#xff08;或者说一个样本、一条训练数据&#xff09;对应一个确定的标签。而多实例的特点就是&#xff0c;我们在训练的时候的输入是多个实例对应一个确定的标签&a…

STM32使用常见错误合集(正在更新版)

本文章记录一些学习STM32的一些错误问题 一、编译、烧录类问题 1、烧录不成功&#xff0c;Keil提示RDDI-DAP Error【场景&#xff1a;PWM驱动直流电机】 解决方案&#xff1a;将电机断开再进行烧录&#xff0c;断开后就可以美美烧录不报错啦~ 二、Keil使用问题 1、打开一个…

【设计模式】-工厂模式

工厂模式是一种创建型设计模式&#xff0c;它提供了一种在不指定具体类的情况下创建对象的方法。工厂模式的核心思想是将对象的创建与使用分离&#xff0c;降低系统的耦合度&#xff0c;使系统更加灵活、可扩展。 工厂模式主要分为三种类型&#xff1a;简单工厂模式、工厂方法…

深入解析JVM加载机制

一、背景 Java代码被编译器变成生成Class字节码&#xff0c;但字节码仅是一个特殊的二进制文件&#xff0c;无法直接使用。因此&#xff0c;都需要放到JVM系统中执行&#xff0c;将Class字节码文件放入到JVM的过程&#xff0c;简称类加载。 二、整体流程 三、阶段逻辑分析 3…

断言assert是什么?

assert是什么&#xff1f; assert断言&#xff0c;是一个被定义在<assert.h>头文件中的一个宏&#xff0c;而不是一个函数。 可以用来检查数据的合法性&#xff0c;但是频繁的调用极大影响了程序的性能&#xff0c;增加了额外的开销。可以通过#define NDEBUG来禁用asse…

【Unity】CatlikeCoding SRP

Unity 自定义渲染管线 提示&#xff1a;基于CatlikeCoding SRP系列教程学习 学习链接&#xff1a;SRP 个人测试: Demo 相关记录以后有时间再更&#xff1a;

CLIP解读

1、引言 在计算机视觉领域&#xff0c;通常需要经过训练模型来实现对预定类别目标预测&#xff08;如分类、检测等任务&#xff09;&#xff0c;但是这种形式会限制模型的通用性。比如我们训练完了一个猫狗分类模型&#xff0c;如果现在希望识别一只老虎&#xff0c;那么原来训…

关于mybatis-plus分页查询total=0问题解决

今天复习分布式架构&#xff0c;一步一步从新架构模块&#xff0c;写道mybatis-plus的时候&#xff0c;突然发现分页查询居然total一直等于0。 在项目上的时候&#xff0c;都是架构师吧这个弄好了的&#xff0c;我一直以为直接分页查询&#xff0c;就会有值&#xff0c;原来还…

如何使用 ArcGIS Pro 分析爆炸波及建筑

创建三维图层 在工具箱中点击“3D Analyst 工具\3D要素\转换\依据属性实现要素转3D”,调用依据属性实现要素转3D工具,如下图所示。 调用依据属性实现要素转3D工具 在显示的依据属性实现要素转3D对话框内,输入要素为爆炸点图层,选择高度字段,如下图所示。 依据属性实现…

2024年个人小型渲染农场搭建是否值得?

个人小型渲染农场的搭建是否值得是一个需要综合考虑的问题。对于那些追求高效渲染和成本控制的创作者来说&#xff0c;个人渲染农场提供了自主控制进度的优势。然而&#xff0c;同时也必须面对技术挑战和初期投资的压力。要决定是否投资个人渲染农场&#xff0c;关键在于权衡技…

结构体中的内存对齐是什么?一起搞懂它

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话&#xff1a; 知不足而奋进&#xff0c;望远山而前行&am…

9成省份“鸿蒙化”,它真起来了?

自去年9月华为宣布鸿蒙原生应用全面启动以来&#xff0c;鸿蒙正以不可阻挡之势&#xff0c;快速在全国千行百业的移动应用领域推进。不仅有支付宝、快手、淘宝、京东等超200家头部互联网企业加入鸿蒙生态&#xff1b;2024年以来&#xff0c;上海、浙江、广西等多省市政务民生、…

QGIS中天地图插件的安装与使用

概述 在QGIS中可添加xyz类型的切片为数据源&#xff0c;一般作为底图加载到地图上。在QGIS中添加xyz类型的切片的操作可参考QGIS CookBook。天地图提供的服务也是xyz类型的切片&#xff0c;但是为提高其加载速度&#xff0c;一般采用了t0-t7多个节点&#xff0c;在QGIS中添加x…

世界第一个AI软件工程师问世!

2024年3月13日&#xff0c;科技公司Cognition推出了世界上第一位人工智能软件工程师Devin AI。这项创新有望利用人工智能编码和机器学习的力量加快发展。Devin AI不仅仅是帮助&#xff1b;它是一个成熟的队友&#xff0c;发挥智能编码自动化和自主人工智能编码的魔力&#xff0…

ElasticSearch 用法

首先讲下 ES的倒排序索引 入门-倒排索引 正排索引&#xff08;传统&#xff09; idcontent1001my name is zhang san1002my name is li si 倒排索引 keywordidname1001, 1002zhang1001 正排索引&#xff1a;我想查name&#xff0c;这时候是模糊的查询&#xff0c;会循环遍历…

【鸿蒙HarmonyOS开发笔记】动画过渡效果之组件内转场动画,内含ForEach动画

概述 我们在开发中难免设计组件的插入、删除过程。通过组件内转场动画&#xff0c;可定义组件出现、消失的效果。 组件内转场动画的接口为&#xff1a; transition(value: TransitionOptions)transition函数的入参为组件内转场的效果&#xff0c;可以定义平移、透明度、旋转…