CCF-CSP真题《202303-3 LDAP》思路+python,c++满分题解

这篇具有很好参考价值的文章主要介绍了CCF-CSP真题《202303-3 LDAP》思路+python,c++满分题解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

想查看其他题的真题及题解的同学可以前往查看:CCF-CSP真题附题解大全


试题编号: 202303-3
试题名称: LDAP
时间限制: 12.0s
内存限制: 1.0GB
问题描述:

题目背景

西西艾弗岛运营公司是一家负责维护和运营岛上基础设施的大型企业,拥有数千名员工。公司内有很多 IT 系统。为了能够实现这些 IT 系统的统一认证登录,公司 IT 部门决定引入一套 LDAP 系统来管理公司内的用户信息。轻型目录访问协议(Lightweight Directory Access Protocol,LDAP)是一种用于访问和维护目录服务的应用层协议,基于它的数据库可以用树形结构来组织和存储数据。每一笔数据,都包含了一个唯一的标识符(DN,Distinguished Name),以及一系列的属性(Attribute)。

不同的 IT 系统,允许访问的用户是不相同的。每个信息系统都有一个表达式,用来描述允许访问的用户。
这个表达式可以按照某一个属性的值作为条件来匹配用户,也可以用多个条件的逻辑组合来匹配用户。
小 C 被安排来实现这样一个算法,给定一个 IT 系统的匹配表达式,找到所有与之匹配的用户的 DN。

问题描述

为了简化该问题,我们约定,每个用户的 DN 是一个正整数,且不会重复。有若干种用户的属性,用正整数编号。每个用户可以具有这些属性中的若干个,且每个属性只能有一个值。每个属性的值也是一个正整数。例如,假定有两个用户:用户 1 和用户 2,他们的 DN 分别是 1 和 2。一共有 3 种属性。用户 1 具有属性 1 和属性 2,且属性 1 的值为 2,属性 2 的值为 3;但不具有属性 3。用户 2 具有属性 2 和属性 3,且属性 2 的值为 3,属性 3 的值为 1;但不具有属性 1。如下表所示:

DN 属性 1 属性 2 属性 3
1 2 3 N/A
2 N/A 3 1

一个匹配表达式可以是一个属性的值,也可以是多个匹配表达式的逻辑组合。只匹配一个属性的值的表达式称为原子表达式,原子表达式的形式为 <属性编号><操作符><属性值>。其中操作符有两种:断言与反断言。断言操作符为 :,表示匹配具有该属性且值与之相等的用户;反断言操作符为 ~,表示匹配具有该属性且值与之不等的用户。例如,表达式 1:2 可以与上述用户 1 相匹配,但不能与用户 2 相匹配;而表达式 3~1则不能与任何一个用户相匹配。

表达式可以进行逻辑组合,其语法是:<操作符>(表达式 1)(表达式 2)。其中操作符有两种:与(&)和或(|)。如果操作符为与,则当且仅当两个表达式都与某一用户相匹配时,该表达式与该用户相匹配;如果操作符为或,则当且仅当两个表达式中至少有一个与某一用户相匹配时,该表达式与该用户相匹配。例如,表达式 &(1:2)(2:3) 可以与用户 1 相匹配,但不能与用户 2 相匹配;而表达式 |(1:2)(3:1) 则可以与两个用户都相匹配。

形式化地,上述语法用 BNF 范式表示如下:

NON_ZERO_DIGIT =  "1" / "2" / "3" / "4" / 
                  "5" / "6" / "7" / "8" / "9"
DIGIT          =  "0" / NON_ZERO_DIGIT
NUMBER         =  NON_ZERO_DIGIT / (NON_ZERO_DIGIT DIGIT*)
ATTRIBUTE      =  NUMBER
VALUE          =  NUMBER
OPERATOR       =  ":" / "~"
BASE_EXPR      =  ATTRIBUTE OPERATOR VALUE
LOGIC          =  "&" / "|"
EXPR           =  BASE_EXPR / (LOGIC "(" EXPR ")" "(" EXPR ")")

EASY_EXPR      =  BASE_EXPR / 
                  (LOGIC "(" BASE_EXPR ")" "(" BASE_EXPR ")")

输入格式

从标准输入读入数据。

输入的第一行包含一个正整数 n,表示用户的数目。

接下来 n 行,每行包含空格分隔的若干个正整数,第一个正整数表示该用户的 DN,第二个正整数表示该用户具有的属性个数,此后的每两个正整数表示该用户具有的一个属性及其值。这些属性按照属性编号从小到大的顺序给出。

接下来一行包含一个正整数 m,表示匹配表达式的数目。

接下来 m 行,每行包含一个匹配表达式。

输出格式

输出到标准输出。

输出 m 行,每行包含零个或多个正整数,用空格分隔,表示与对应的匹配表达式相匹配的用户的 DN,由小到大排序。

样例输入1

2
1 2 1 2 2 3
2 2 2 3 3 1
4
1:2
3~1
&(1:2)(2:3)
|(1:2)(3:1)

样例输出1

1

1
1 2

样例解释

本组输入是题目描述中的例子。

子任务

对于 20% 的输入,有 1≤n≤100,1≤m≤10,每个用户的属性个数不超过 10,全部属性编号不超过 100,且表达式是原子表达式,即符合 BNF 语法 BASE_EXPR

对于 40% 的输入,有 1≤m≤100,每个用户的属性个数不超过 10,全部属性编号不超过 100,且表达式中至多含有两个原子表达式的逻辑组合,即符合 BNF 语法 EASY_EXPR

对于 70% 的输入,有全部属性编号不超过 500。

对于全部输入,有 1≤n≤2500,1≤m≤500,每个用户的属性个数不超过 500,全部属性编号、属性值和 DN 均不超过 109,每个表达式语句都符合题设语法,且语句字符长度不超过 2000。

真题来源:LDAP

感兴趣的同学可以如此编码进去进行练习提交

思路分析:

        主要是要解决表达式嵌套的问题,与栈实现计算器时维护一个符号栈、一个数值栈类似。这里维护了两个栈,一个符号栈op,一个bitset集合栈stk,集合求交、或,由bitset完成。当遇到&或|时,将符号压栈;当遇到)时,将bitset压栈;()内正常读取,求bitset即可。当同一个符号对应两个bitset在栈内(num[c]=2)时,将两个bitset运算为一个bitset。其余部分map乱搞,q[i][j]表示DN=i用户的j属性值,p(i,j)表示i属性值为j的有哪些用户,has[i]表示i属性有哪些用户,i:j操作时,p[i][j]即为所求;i~j操作时,has[i]内去掉p[i][j]即为所求。to[i]记录了第i个用户对应的DN值,输出时按DN从小到大排序即可。

 c++满分题解:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
const int N=2502;
int n,m,sz,id,k,c,d,x,y,num[N],to[N],f[N];
map<int,int>q[N];
map<P,vector<int>>p;
map<int,vector<int>>has;
char s[N],op[N];
bitset<N>stk[N*2],res;
bitset<N>cal(int l,char x,int r){
	bitset<N>ans;
	for(auto &v:p[P(l,r)]){
		ans.set(v);
	}
	if(x=='~'){
		for(auto &v:has[l]){
			ans.flip(v);
		}
	}
	return ans;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%d%d",&id,&k);
		to[i]=id;
		for(int j=1;j<=k;++j){
			scanf("%d%d",&x,&y);
			q[i][x]=y;
			has[x].push_back(i);
			p[P(x,y)].push_back(i);
		}
	}
	scanf("%d",&m);
	for(int i=1;i<=m;++i){
		scanf("%s",s);
		sz=strlen(s);
		c=d=0;
		for(int j=0;j<sz;){
			if(s[j]=='&' || s[j]=='|'){
				op[++c]=s[j++];
			}
			else if(s[j]=='('){
				j++;
			}
			else if(s[j]==')'){
				num[c]++;
				if(num[c]==2){
					d--;
					if(op[c]=='&')stk[d]=stk[d]&stk[d+1];
					else stk[d]=stk[d]|stk[d+1];
					num[c--]=0;
				}
				j++;
			}
			else{
				int cur=j,l=0,r=0;
				while(cur<sz && (s[cur]!=':' && s[cur]!='~')){
					l=l*10+(s[cur]-'0');
					cur++;
				}
				char x=s[cur++];
				while(cur<sz && s[cur]!=')'){
					r=r*10+(s[cur]-'0');
					cur++;
				}
				stk[++d]=cal(l,x,r);
				j=cur;
			}
		}
		int e=0;
		for(int j=1;j<=n;++j){
			if(stk[d].test(j)){
				f[++e]=to[j];
			}
		}
		sort(f+1,f+e+1);
		for(int j=1;j<=e;++j){
			printf("%d%c",f[j]," \n"[j==e]);
		}
		if(!e)puts("");
	}
	return 0;
}

运行结果:

CCF-CSP真题《202303-3 LDAP》思路+python,c++满分题解,算法题练习,python,c++,开发语言文章来源地址https://www.toymoban.com/news/detail-526272.html

到了这里,关于CCF-CSP真题《202303-3 LDAP》思路+python,c++满分题解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • CCF-CSP真题《202305-3 解压缩》思路+python,c++满分题解

    想查看其他题的真题及题解的同学可以前往查看:CCF-CSP真题附题解大全 试题编号: 202305-3 试题名称: 解压缩 时间限制: 5.0s 内存限制: 512.0MB 问题描述: 西西艾弗岛运营公司是一家负责维护和运营岛上基础设施的大型企业。在公司内,有许多分管不同业务的部门都需要使

    2024年02月13日
    浏览(55)
  • CCF-CSP真题《202305-1 重复局面》思路+python,c++满分题解

    想查看其他题的真题及题解的同学可以前往查看:CCF-CSP真题附题解大全 试题编号: 202305-1 试题名称: 重复局面 时间限制: 1.0s 内存限制: 512.0MB 问题描述: 国际象棋在对局时,同一局面连续或间断出现3次或3次以上,可由任意一方提出和棋。 国际象棋每一个局面可以用大

    2024年02月13日
    浏览(66)
  • CCF-CSP真题《202305-2 矩阵运算》思路+python,c++满分题解

    想查看其他题的真题及题解的同学可以前往查看:CCF-CSP真题附题解大全 试题编号: 202305-2 试题名称: 矩阵运算 时间限制: 5.0s 内存限制: 512.0MB 问题描述: Softmax(Q×KTd)×V 是 Transformer 中注意力模块的核心算式,其中 Q、K 和 V 均是 n 行 d 列的矩阵,KT 表示矩阵 K 的

    2024年02月16日
    浏览(49)
  • CCF-CSP真题《202309-1 坐标变换(其一)》思路+python,c++,java满分题解

    想查看其他题的真题及题解的同学可以前往查看:CCF-CSP真题附题解大全 试题编号: 202309-1 试题名称: 坐标变换(其一) 时间限制: 1.0s 内存限制: 512.0MB 问题描述: 对于平面直角坐标系上的坐标 (x,y),小 P 定义了一个包含 n 个操作的序列 T=(t1,t2,⋯,tn)。其中每个操作 

    2024年02月08日
    浏览(44)
  • CCF-CSP 29次 第三题【202303-3 LDAP】

    数据结构:结构体数组、哈希表 原子表达式:处理很简单,利用 string 中的 find() 函数找到 : 或 ~ 的位置下标,左边为 key ,右边为 value ,遍历结构体数组寻找匹配的用户。 表达式的逻辑组合: (...)(...) 括号内也可以是逻辑组合,如 (|(1:2)(3~4))(101:202) 。注意不会出现 (...)(...)

    2024年02月06日
    浏览(45)
  • CCF-CSP历年真题大全附题解(202303已更)

             各位朋友,历年的题目你们要是有不同的解法想和大家进行分享的,可以私聊我发我题目编号和代码,我也可以更新到文章中,给需要的朋友多点参考~~           CCF-CSP真题拿来练手,持续更新,CCF-CSP真题拿来练手,如果对自己没有拿高分的期望的话,可以就

    2024年02月01日
    浏览(78)
  • 第29次CCF CSP 认证题目 第一题 202303-1 田地丈量 C++实现 满分答案

    西西艾弗岛上散落着 n 块田地。每块田地可视为平面直角坐标系下的一块矩形区域,由左下角坐标 (x1,y1) 和右上角坐标 (x2,y2) 唯一确定,且满足 x1x2、y1y2。这 n 块田地中,任意两块的交集面积均为 0,仅边界处可能有所重叠。 最近,顿顿想要在南山脚下开垦出一块面积

    2023年04月15日
    浏览(56)
  • CCF-CSP认证 202303 500分题解

    202303-1 田地丈量(矩形面积交) 矩形面积交=x轴线段交长度*y轴线段交长度 线段交长度,相交的时候是min右端点-max左端点,不相交的时候是0 202303-2 垦田计划(二分) 二分最终答案x(x=k),判断降到x天资源是否够 够的话就往小里二分,否则往大里二分, 当然贪心也可以做

    2023年04月18日
    浏览(50)
  • CCF-CSP 29次 第五题【202303-5 施肥】

    计算机软件能力认证考试系统 题解(35分): 枚举每个区间,再枚举每个施肥车,看所有的施肥车能不能把这个区间填满

    2024年02月10日
    浏览(98)
  • CCF-CSP 29次 第二题【202303-2 垦田计划】

    法一: 70分:优先队列 对基础耗时大的优先进行处理 法二: 100分:二分答案 法三:对法一的改进 100分:对相同耗时的区域合并处理 同样从耗时最多的区域开始

    2024年02月07日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包