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
123N/A
2N/A31

一个匹配表达式可以是一个属性的值,也可以是多个匹配表达式的逻辑组合。只匹配一个属性的值的表达式称为原子表达式,原子表达式的形式为 <属性编号><操作符><属性值>。其中操作符有两种:断言与反断言。断言操作符为 :,表示匹配具有该属性且值与之相等的用户;反断言操作符为 ~,表示匹配具有该属性且值与之不等的用户。例如,表达式 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;
}

运行结果:

  • 9
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: CCF-CSP(中国计算机学会认证系统程序员)认证考试是由中国计算机学会主办的,旨在选拔高水平的系统程序员和开发人员。该认证考试包括两个级别:初级和高级。初级考试主要测试候选人的基础知识和编程能力,高级考试则主要测试候选人的系统设计和开发能力。CCF-CSP认证考试的评分标准严格,要求考生表现出扎实的计算机理论基础和熟练的编程技巧。 为了顺利通过CCF-CSP认证考试,考生需要掌握扎实的计算机基础知识和熟练的编程技巧,并且需要在考试前进行充分的准备。以下是一些复习技巧指导: 1. 确认考试大纲 考生需要仔细阅读考试大纲,了解考试范围和题型。要特别注意考试大纲中的重点内容,重点复习。 2. 提前规划复习进度 准备CCF-CSP认证考试需要时间,而时间是很宝贵的,考生需要提前规划好复习进度和复习内容,尽可能利用零散时间进行复习。 3. 多做题 要想掌握CCF-CSP认证考试所需的知识和技能,考生需要多做题,并针对性地练习一些经典的考题。在练习中,考生需要注重练习思路和解题方法,该方法可以加深对知识点的理解。 4. 关注考试动态 考试动态指的是考试历年来的趋势和变化,考生需要不断关注考试动态,了解考试趋势,及时更新复习内容和方法,以便更好地应对考试。 总之,要想通过CCF-CSP认证考试,考生需要理论基础和开发经验充足,并且需要在复习时切实遵循学科规范,灵活应用知识点,较好地掌握考试技巧,这是顺利通过CCF-CSP认证考试的关键。 ### 回答2: ccf-csp认证考试是中国计算机学会(CCF)认证的一个计算机软件专业技能等级考试,也是中国IT行业里非常重要的证书之一。该考试分为初级、中级和高级三个等级,其中初级考试包含了基础的程序设计和算法等内容,中级考试中主要考察了软件工程、数据结构、算法设计和网络安全等领域的知识,而高级考试则更注重的是对软件工程和软件项目管理的理解和应用,以及对复杂系统的设计和实现方法的掌握。为了能够成功通过ccf-csp认证考试,首先需要在考前充分准备,并且需要有一些好的复习技巧,这里向大家推荐以下几点: 1.学好基础知识。初级、中级和高级csp认证考试所涉及到的内容都是建立在一定的基础知识上的。由于考试的难度逐级递增,所以建议在准备考试之前先花时间学好基础知识。 2.多做练习题。做练习题能够帮助我们加深对知识的理解,熟悉考试形式和规则,同时也能提高我们的答题速度和准确度。 3.注意时间管理。不同级别的csp认证考试都有时限,在考试过程中需要注意时间的分配。建议在每次做练习题的时候都设置一个时间限制,并逐步缩短时间限制,以提高答题效率。 4.了解考试规则。在考前一定要熟悉考试规则和题型,知道考试时可以携带哪些资料和工具,了解考试的答题和评分规则等。 总之,ccf-csp认证考试是一项非常重要的认证考试,通过这个认证不仅可以增加个人的职业竞争力,还能证明个人在软件开发和IT行业方面的专业能力。因此,我们需要认真地准备和复习,字斟句酌地做好每一个细节,以确保顺利通过考试。 ### 回答3: ccf-csp认证考试是由中国计算机学会主办的全国性计算机考试,考试内容涵盖了计算机应用、技术、算法等多个方面,分为初级、中级和高级三个等级。参加此考试不仅有助于检测个人的计算机专业水平,更能提升自身的竞争力和职业发展前景。 为了通过ccf-csp认证考试,考生需要重点复习考试要求中的各个内容模块,如数据类型、运算符、控制结构、数组、函数、文件操作等程序设计相关方面;还包括计算机网络、操作系统、数据库等计算机技术类知识;另外,还需要掌握常见算法和数据结构,如排序、查找、树等。此外,考生还需要通过大量的编程练习和模拟题练习,熟悉考试题型和答题技巧,提升自己的完成效率和准确性。 在复习过程中,需要注重细节和实践。例如,对于程序设计相关方面,需要理解每个知识点的原理和应用场景,在编写代码时要注重细节避免出现错误。对于算法和数据结构方面,需要熟悉常见算法的实现方式和优缺点,掌握好算法的时间复杂度和空间复杂度,做到熟练掌握。 总之,通过充分准备和钻研,考生有望成功通过ccf-csp认证考试,展现自己的计算机专业能力和职业素养。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hulake_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值