【河南省第十一届ACM大学生程序设计竞赛-D】.求XF+闭包
如何设计一个好的数据库不仅仅是一个理论研究问题,也是一个实际应用问题。在关系数据库中不满足规范化理论的数据库设计会存在冗余、插入异常、删除异常等现象。
设R(U)是一个关系模式,U={ A1,A2, ……, An}。其中Ai是关系的属性,X,Y是U的子集。函数依赖 XàY 定义了数据库中属性集X与Y的依赖关系。根据Armstrong公理,函数依赖满足:
(1) 自反律:若Ai∈X, 则 X->Ai . 特别地,Ai->Ai .
(2) 增广律:若 X->Y, 则 ZX->ZY. (ZX 是指集合Z与X的并集 )
(3) 传递律:若 X->Y, Y->Z, 则 X->Z.
(4) 分解律:若 X->Y, 则 X->Ai ( 若属性Ai∈Y )
(5) 合并律:若 X->Y, X->Z, 则 X->YZ.
已知 F 是关系模式R(U)上的函数依赖集,利用Armstrong公理系统可以推导出更多的函数依赖。设X是属性集U={ A1,A2, ……, An} 的子集, 定义X关于F的闭包XF+
XF+={ Ai | 若X-> Ai可以通过Armstrong公理导出}
对于给定的U , F ,X, 请求出XF+
【标准输入】
第一行: T 表示以下有T组测试数据 ( 1≤T ≤5 )
对每组数据,
第1行: n m k
n 表示U中属性个数( 1≤n≤26 ), 用大写字母表示
m表示X中属性个数( 1≤m≤26 )
k个函数依赖 (1≤ k ≤ 20 )
第2行: 字符串U n个大写字母
第3行: 字符串X m个大写字母
接下来有K行,每行有两个字符串 S T,用一个空格隔开。 表示 S->T
【标准输出】
对每组测试数据,输出占一行输出XF+,要求按字母序输出。
【 样 例 】
标准输入 |
标准输出 |
1 6 2 4 ABGDCI AD A B BD I AG C C D |
ABDI |
我的做法是暴力,假设左集所有的元素都在闭包集中,那么可以推出右集也在闭包集中,因为最多26个字母,多循环几次就可以得到答案。
#include <bits/stdc++.h> using namespace std; struct node { char s1[30], s2[30]; } q[28]; int main() { int t, i, n, m; cin>>t; int a[30]; while(t--) { scanf("%d%d%d", &i, &n, &m); char s[30], str[30]; scanf("%s", str); scanf("%s", s); for(int i = 1; i <= m; i++) { scanf("%s%s", q[i].s1, q[i].s2); } memset(a, 0, sizeof a); int l = strlen(s); for(int i = 0; i < l; i++) { a[s[i]-'A']++; } while(1) { bool flag = 0; for(int i = 1; i <= m; i++) { int l1 = strlen(q[i].s1); bool f = 1; for(int j = 0; j < l1; j++) { if(!a[q[i].s1[j]-'A']) f = 0; } if(f) { int l2 = strlen(q[i].s2); for(int k = 0; k < l2; k++) { if(!a[q[i].s2[k]-'A']) { a[q[i].s2[k]-'A']++; flag = 1; } } } } if(!flag) break; } l = strlen(str); for(int i = 0; i < l; i++) { if(a[str[i]-'A']) printf("%c", str[i]); } cout<<endl; } return 0; }