202303 CSP认证 | LDAP

news2024/11/16 2:16:37

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;
}

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024全新红娘交友系统定制版源码 | 相亲交友小程序源码 全开源可二开

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 全新红娘交友系统定制版源码 | 相亲交友小程序源码 全开源可二开 定制版红娘交友平台小程序源码&#xff0c;很牛逼的东西&#xff0c;虽然是小程序&#xff0c;但是有700多M大&…

LeetCode每日一题【59.螺旋矩阵Ⅱ】

思路&#xff1a;模拟&#xff0c;给出上下左右4个方向的边界&#xff0c;逐步收缩 class Solution { public:vector<vector<int>> generateMatrix(int n) {int left 0;int right n-1;int top 0;int bottom n-1;int k 1;vector<vector<int>> ans…

七、链表问题(中)

2、两数相加&#xff08;中等&#xff09; 题目描述 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以…

window 查看特定端口占用并停掉

要查看Windows上特定端口的占用情况并停止相关进程&#xff0c;你可以使用以下步骤&#xff1a; 查看端口占用&#xff1a; 首先&#xff0c;你可以使用netstat命令来查看特定端口的占用情况。假设你想要查看端口号为8080的情况&#xff0c;你可以运行以下命令&#xff1a; net…

力扣● 583. 两个字符串的删除操作 ● 72. 编辑距离 ● 编辑距离总结篇

● 583. 两个字符串的删除操作 注意审题&#xff1a; 给定两个单词 word1 和 word2 &#xff0c;返回使得 word1 和 word2 相同所需的最小步数。 每步 可以删除任意一个字符串中的一个字符。 删除最少的字符使两者相同&#xff0c;说明留下来的就是最大公共子序列。不要求…

谷歌google adsense广告申请提示:网站已下线或无法访问

自己在运营网站时&#xff0c;想在网站上挂google adsense广告&#xff0c;但是申请很多次&#xff0c;收到的邮件都是您需要先纠正一些问&#xff0c;登陆google adsense后台显示&#xff0c;网站已下线或无法访问。 重新申请多次问题依旧&#xff0c;我在想为什么国外无法访…

一个可商用私有化部署的基于JAVA的chat-gpt网站

目录 介绍一、核心功能1、智能对话2、AI绘画3、知识库4、一键思维导图5、应用广场6、GPTS 二、后台管理功能1、网站自定义2、多账号登录支持3、商品及会员系统4、模型配置5、兑换码生成6、三方商户用户打通 结语 介绍 java语言的私有化部署的商用网站还是比较少的 这里给大家介…

C语言中大小写字母如何转化

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

GaussDB数据库的索引管理

目录 一、引言 二、GaussDB数据库中的索引基本概念 1. 什么是GaussDB索引&#xff1f; 2. GaussDB索引的作用 三、GaussDB支持的索引类型 1. B-Tree索引 2. GIN索引 3. GiST索引 4. SP-GiST索引 四、创建和管理GaussDB索引 1. 创建索引 2. 删除索引 3. 索引的优化…

主键约束

Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 主键约束可以看成是非空约束再加上唯一约束 也就是说设置为主键列&#xff0c;不能为空&#xff0c;不能重复 像一般用户编号是不可能重复的&#xff0c;也不可能为空的 …

如何解决网络中IP地址发生冲突故障?

0、前言 本专栏为个人备考软考嵌入式系统设计师的复习笔记&#xff0c;未经本人许可&#xff0c;请勿转载&#xff0c;如发现本笔记内容的错误还望各位不吝赐教&#xff08;笔记内容可能有误怕产生错误引导&#xff09;。 1、个人IP地址冲突解决方案 首先winR&#xff0c;调出…

KWJL-20/L智能电流继电器0.1-50A 零序互感器KWLD26Φ45JOSEF约瑟

KWJL-20/L智能电流继电器 KWLD20零序电流互感器 KWLD26零序电流互感器 KWLD45零序电流互感器 KWLD80零序电流互感器 产品概述 KWJL-20系列智能电流继电器&#xff08;以下简称继电器&#xff09;适用于交流电压至660V或更高的TN、TT、和IT系统&#xff0c;频率为50Hz。通…

CSS 绝对定位 position:absolute

什么是CSS绝对定位absolute定位&#xff1f; 绝对定位absolute定位是CSS中的一种定位方式&#xff0c;可以将元素精确定位到一个确定的点&#xff0c;这与元素在文档流上的自然位置无关。相比起其他定位方式&#xff0c;绝对定位很灵活性&#xff0c;它可以将元素脱离文档流&am…

Session会话绑定

1.需求原因 用户的请求,登录的请求,经过负载均衡后落到后面的web服务器上,登录的状态/信息也会记录在web服务器上,就会导致不通的web服务器上,登录状态不统一,造成用户频繁需要登录 2.目标&#xff1a;如何实现会话保持/会话共享 方案一&#xff1a;登录状态写入cookie中.(wor…

机器学习----特征缩放

目录 一、什么是特征缩放&#xff1a; 二、为什么要进行特征缩放&#xff1f; 三、如何进行特征缩放&#xff1a; 1、归一化&#xff1a; 2、均值归一化&#xff1a; 3、标准化&#xff08;数据需要符合正态分布&#xff09;&#xff1a; 一、什么是特征缩放&#xff1a; 通…

C++_day6

思维导图&#xff1a; 2试编程 封装一个动物的基类&#xff0c;类中有私有成员: 姓名&#xff0c;颜色&#xff0c;指针成员年纪 再封装一个狗这样类&#xff0c;共有继承于动物类&#xff0c;自己拓展的私有成员有:指针成员:腿的个数(整型 int count)&#xff0c;共有成员函数…

GAMES101 学习 2

Lecture 7&#xff1a;Shading 1(lllumination,Shading and Graphics Pipeline) Visibility / occlusion 解决可见性和遮挡的问题 可见性&#xff0c;Z-buffering Z-Buffer 深度缓存 Idea&#xff1a; Store current min. z-value for each sample (pixel)Needs an additi…

MS16_016 漏洞利用与安全加固

文章目录 环境说明1 MS16_016 简介2 MS16_016 复现过程3 MS16_016 安全加固 环境说明 渗透机操作系统&#xff1a;kali-linux-2024.1-installer-amd64漏洞复现操作系&#xff1a;cn_windows_7_professional_with_sp1_x64_dvd_u_677031 1 MS16_016 简介 MS16_016 漏洞产生的原因…

类和对象-1

文章目录 面向过程和面向对象的概念类的引入访问限定符类的大小this指针 面向过程和面向对象的概念 面向过程是一种按照步骤顺序执行的编程方式&#xff0c;而面向对象则是以对象为中心&#xff0c;将数据和操作封装在一起。在面向对象编程中&#xff0c;可以通过定义类和对象来…