【河南省第十一屆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; }
【河南省第十一屆ACM大學生程序設計競賽-D】.求XF+閉包