├── README.md ├── 编程1:求命题公式的主范式.cpp ├── 编程2:消解算法.cpp ├── 编程3:求关系的传递闭包.cpp ├── 编程4:求偏序集中的极大元与极小元.cpp ├── 编程5:求函数的逆元.cpp ├── 编程6:求元素的阶.cpp ├── 编程7:二部图的判定.cpp └── 编程8:有向图连通性的判定.cpp /README.md: -------------------------------------------------------------------------------- 1 | # 离散数学上机题 2 | 北京理工大学(北理工)“离散数学”课程编程作业。 3 | 4 | ## 📒内容 5 | 6 | |序号|内容|代码| 7 | |:-:|:-:|:-:| 8 | |1|求命题公式的主范式|[CPP](./编程1:求命题公式的主范式.cpp)| 9 | |2|消解算法|[CPP](./编程2:消解算法.cpp)| 10 | |3|求关系的传递闭包|[CPP](./编程3:求关系的传递闭包.cpp)| 11 | |4|求偏序集中的极大元与极小元|[CPP](./编程4:求偏序集中的极大元与极小元.cpp)| 12 | |5|求函数的逆元|[CPP](./编程5:求函数的逆元.cpp)| 13 | |6|求元素的阶|[CPP](./编程6:求元素的阶.cpp)| 14 | |7|二部图的判定|[CPP](./编程7:二部图的判定.cpp)| 15 | |8|有向图连通性的判定|[CPP](./编程8:有向图连通性的判定.cpp)| 16 | 17 | ## 😁说明 18 | 19 | 由于距离编写代码时间久远和代码注释不全面等原因,代码的可读性下降,还望谅解。 20 | -------------------------------------------------------------------------------- /编程1:求命题公式的主范式.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class expression{ 10 | public: 11 | expression(string s){ 12 | this->s=s; 13 | } 14 | int ans(){ 15 | for(int i=0;i=priority(s[i])){ 41 | char temp=opt.top(); 42 | opt.pop(); 43 | if(temp=='!'){ 44 | int a=num.top(); 45 | num.pop(); 46 | num.push(calc(a,-1,temp)); 47 | } 48 | else{ 49 | int a=num.top(); 50 | num.pop(); 51 | int b=num.top(); 52 | num.pop(); 53 | num.push(calc(a,b,temp)); 54 | } 55 | opt.push(s[i]); 56 | } 57 | } 58 | else{ 59 | num.push(s[i]-48); 60 | } 61 | } 62 | while(!opt.empty()){ 63 | char temp=opt.top(); 64 | opt.pop(); 65 | if(temp=='!'){ 66 | int a=num.top(); 67 | num.pop(); 68 | num.push(calc(a,-1,temp)); 69 | } 70 | else{ 71 | int a=num.top(); 72 | num.pop(); 73 | int b=num.top(); 74 | num.pop(); 75 | num.push(calc(b,a,temp)); 76 | } 77 | } 78 | return num.top(); 79 | } 80 | private: 81 | string s; 82 | stack opt; 83 | stack num; 84 | bool isopt(char c){ 85 | if(c=='!'||c=='&'||c=='|'||c=='-'||c=='+') return true; 86 | else return false; 87 | } 88 | int priority(char c){ 89 | if(c=='!') return 6; 90 | else if(c==')') return 5; 91 | else if(c=='&') return 4; 92 | else if(c=='|') return 3; 93 | else if(c=='-') return 2; 94 | else if(c=='+') return 1; 95 | else if(c=='(') return 0; 96 | } 97 | int calc(int a,int b,char c){ 98 | switch(c){ 99 | case '&': 100 | if(a==1&&b==1) return 1; 101 | else return 0; 102 | break; 103 | case '|': 104 | if(a==0&&b==0) return 0; 105 | else return 1; 106 | break; 107 | case '-': 108 | if(a==1&&b==0) return 0; 109 | else return 1; 110 | break; 111 | case '+': 112 | if(a==1&&b==0||a==0&&b==1) return 0; 113 | else return 1; 114 | break; 115 | case '!': 116 | if(a==0) return 1; 117 | else return 0; 118 | break; 119 | } 120 | } 121 | }; 122 | 123 | class principalNormalForm{ 124 | public: 125 | principalNormalForm(string s){ 126 | this->s=s; 127 | numVariables=0; 128 | numTrueValue=0; 129 | } 130 | void solve(){ 131 | countVariables(); 132 | DFS(0); 133 | if(numTrueValue==0) cout<<"0"; 134 | else 135 | for(int i=0;i1) cout<<" ∧ "; 151 | numFalseValue--; 152 | } 153 | cout< variables; 159 | int tempTrueTable[15]; 160 | int trueValue[1000]; 161 | int numTrueValue; 162 | bool isopt(char c){ 163 | if(c=='!'||c=='&'||c=='|'||c=='-'||c=='+') 164 | return true; 165 | else return false; 166 | } 167 | void countVariables(); 168 | void DFS(int n); 169 | }; 170 | 171 | void principalNormalForm::countVariables(){ 172 | int len=s.length(); 173 | string temp; 174 | int start=0,end=0; 175 | for(int i=0;i>s; 232 | principalNormalForm obj(s); 233 | obj.solve(); 234 | system("pause"); 235 | return 0; 236 | } -------------------------------------------------------------------------------- /编程2:消解算法.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | class digestion{ 8 | public: 9 | digestion(string s){ 10 | this->s=s; 11 | } 12 | void solve(){ 13 | init(); 14 | bool ans=calc(); 15 | if(ans==true) 16 | cout<<"YES"< S0; 23 | vector S1; 24 | vector S2; 25 | void init(); 26 | bool calc(); 27 | bool Res(string s1,string s2,string &res); 28 | }; 29 | 30 | void digestion::init(){ 31 | int len=s.length(); 32 | string temp; 33 | for(int i=0;i s1_;//存放s1的文字 91 | for(int i=0;i s2_;//存放s2的文字 108 | for(int i=0;i>s; 154 | digestion obj(s); 155 | obj.solve(); 156 | system("pause"); 157 | return 0; 158 | } -------------------------------------------------------------------------------- /编程3:求关系的传递闭包.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | 8 | int main(){ 9 | int M[100][100]; 10 | int n=0,a,temp[1000],i=0; 11 | while(scanf("%d",&a)!=EOF){ 12 | temp[i++]=a; 13 | } 14 | n=sqrt(i); 15 | for(int i=0;i 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | 9 | 10 | int main(){ 11 | int eleNum[30][2],eleCount=0; 12 | char relatation[30][2]; 13 | char s[100]; 14 | gets(s); 15 | for(int i=0;i='a'&&s[i]<='z'){ 17 | eleNum[s[i]-'a'][0]=1; 18 | eleNum[s[i]-'a'][1]=0; 19 | eleCount++; 20 | } 21 | } 22 | int n=0; 23 | char a,b; 24 | while(scanf("<%c,%c>",&a,&b)!=EOF){ 25 | getchar(); 26 | relatation[n][0]=a; 27 | relatation[n][1]=b; 28 | eleNum[a-'a'][1]++; 29 | eleNum[b-'a'][1]++; 30 | n++; 31 | } 32 | vector min; 33 | vector max; 34 | for(int i=0;i 2 | using namespace std; 3 | // 设A={x|x属于R, x不等于0,1},在A上定义6个函数, 4 | // f1(x)=x, f2(x)=x^-1, f3(x)=1-x, 5 | // f4(x)=(1-x)^-1, f5(x)=(x-1)x^-1, f6(x)= x(x-1)^-1, 6 | // *运算为函数的复合运算, 求函数的逆元。 7 | //首先明确元素是函数,运算符为函数复合;其次明确单位元为恒等函数,即为f1 8 | //然后给出运算表 9 | // f1 f2 f3 f4 f5 f6 10 | // f1 f1 f2 f3 f4 f5 f6 11 | // f2 f2 f1 f4 f3 f6 f5 12 | // f3 f3 f5 f1 f6 f2 f4 13 | // f4 f4 f6 f2 f5 f1 f3 14 | // f5 f5 f3 f6 f1 f4 f2 15 | // f6 f6 f4 f5 f2 f3 f1 16 | int main(){ 17 | //res中存储运算表 18 | int res[6][6]={{1,2,3,4,5,6}, 19 | {2,1,4,3,6,5}, 20 | {3,5,1,6,2,4}, 21 | {4,6,2,5,1,3}, 22 | {5,3,6,1,4,2}, 23 | {6,4,5,2,3,1}}; 24 | char c; 25 | int n; 26 | cin>>c>>n; 27 | for(int i=0;i<6;i++){ 28 | if(res[n-1][i]==1){//找到了右逆元,判断其是否为左逆元 29 | if(res[i][n-1]==1){ 30 | cout<<"f"< 2 | using namespace std; 3 | // 设Z18为模18整数加群,求元素的阶。 4 | //首先明确单位元为0,然后判断元素的几次方幂为单位元 5 | int main(){ 6 | int n; 7 | cin>>n; 8 | int sum=0; 9 | int j=0;//j表示节阶 10 | do{ 11 | sum+=n; 12 | j++; 13 | if(sum>=18) sum%=18; 14 | }while(sum!=0); 15 | cout< 2 | #include 3 | using namespace std; 4 | const int N = 100; 5 | class Graph 6 | { 7 | private: 8 | int n; 9 | int matrix[N][N]; 10 | public: 11 | Graph() 12 | { 13 | cin >> n; 14 | for (int i = 0; i < n; i++) 15 | { 16 | for (int j = 0; j < n; j++) 17 | { 18 | cin >> matrix[i][j]; 19 | } 20 | } 21 | } 22 | void bfs() 23 | { 24 | int color[N] = { 0 }; 25 | int visit[N] = { 0 }; 26 | color[0] = 1; 27 | visit[0] = 1; 28 | queueq; 29 | q.push(0); 30 | while (!q.empty()) 31 | { 32 | int t = q.front(); 33 | q.pop(); 34 | for (int i = 0; i < n; i++) 35 | { 36 | if (matrix[t][i] > 0) 37 | { 38 | if (color[t] == color[i] || t == i) 39 | { 40 | cout << "no" << endl; 41 | return; 42 | } 43 | else if (color[i] == 0) 44 | { 45 | color[i] = -color[t]; 46 | q.push(i); 47 | visit[i] = 1; 48 | } 49 | } 50 | } 51 | if (q.empty()) 52 | { 53 | for (int i = 1; i < n; i++) 54 | { 55 | if (visit[i] == 0) 56 | { 57 | q.push(i); 58 | color[i] = 1; 59 | visit[i] = 1; 60 | break; 61 | } 62 | } 63 | } 64 | } 65 | cout << "yes" << endl; 66 | } 67 | }; 68 | int main() 69 | { 70 | Graph G; 71 | G.bfs(); 72 | return 0; 73 | } -------------------------------------------------------------------------------- /编程8:有向图连通性的判定.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | int main() 5 | { 6 | 7 | int a[100][100]; 8 | int b[100][100]; 9 | int c[100][100]; 10 | int d[100][100]; 11 | int e[100][100]; 12 | int sum[100][100]; 13 | int sum2[100][100]; 14 | int count = 0, flag1 = 2, flag2 = 2, flag3 = 2; 15 | int n; 16 | 17 | cin >> count; 18 | n = count; 19 | for (int i = 0; i < n; i++) 20 | { 21 | for (int j = 0; j < n; j++) 22 | { 23 | cin >> a[i][j]; 24 | } 25 | } 26 | 27 | for (int i = 0; i < n; i++) 28 | { 29 | for (int j = 0; j < n; j++) 30 | { 31 | sum[i][j] = a[i][j]; 32 | } 33 | } 34 | 35 | for (int i = 0; i < n; i++) 36 | for (int j = 0; j < n; j++) 37 | for (int z = 0; z < n; z++) 38 | { 39 | b[i][j] += a[i][z] * a[z][j]; 40 | } 41 | 42 | count = count - 2; 43 | 44 | for (int i = 0; i < n; i++) 45 | for (int j = 0; j < n; j++) 46 | { 47 | sum[i][j] = sum[i][j] + b[i][j]; 48 | } 49 | 50 | // 处理成可达矩阵 51 | while (count != 0) 52 | { 53 | 54 | for (int i = 0; i < n; i++) 55 | for (int j = 0; j < n; j++) 56 | for (int z = 0; z < n; z++) 57 | { 58 | c[i][j] += b[i][z] * a[z][j]; 59 | } 60 | count = count - 1; 61 | 62 | for (int i = 0; i < n; i++) 63 | for (int j = 0; j < n; j++) 64 | { 65 | sum[i][j] = sum[i][j] + c[i][j]; 66 | } 67 | 68 | memcpy(b, c, sizeof(c)); 69 | memset(c, 0, sizeof(c)); 70 | } 71 | 72 | for (int i = 0; i < n; i++) 73 | for (int j = 0; j < n; j++) 74 | { 75 | if (sum[i][j] != 0) 76 | sum[i][j] = 1; // 此时矩阵为可达矩阵 77 | } 78 | 79 | for (int i = 0; i < n; i++) 80 | for (int j = 0; j < n; j++) 81 | { 82 | if (sum[i][j] != 1) 83 | flag1 = 0; // 不是强连通 84 | } 85 | 86 | if (flag1 != 0) 87 | flag1 = 1; 88 | 89 | for (int i = 0; i < n; i++) 90 | for (int j = 0; j < n; j++) 91 | { 92 | if (i != j) 93 | { 94 | if (sum[i][j] + sum[j][i] <= 0) 95 | flag2 = 0; // 不是单向连通 96 | } 97 | } 98 | 99 | if (flag2 != 0) 100 | flag2 = 1; 101 | 102 | // 判断弱连通情况 103 | 104 | if (flag1 == 0 && flag2 == 0) 105 | { 106 | for (int i = 0; i < n; i++) 107 | for (int j = 0; j < n; j++) 108 | { 109 | if (i != j) 110 | { 111 | if (a[i][j] == 1 || a[j][i] == 1) 112 | { 113 | a[i][j] = a[j][i] = 1; // 新的邻接矩阵 114 | } 115 | } 116 | } 117 | 118 | for (int i = 0; i < n; i++) 119 | for (int j = 0; j < n; j++) 120 | { 121 | sum2[i][j] = a[i][j]; 122 | } 123 | 124 | for (int i = 0; i < n; i++) 125 | for (int j = 0; j < n; j++) 126 | for (int z = 0; z < n; z++) 127 | { 128 | d[i][j] += a[i][z] * a[z][j]; 129 | } 130 | 131 | for (int i = 0; i < n; i++) 132 | for (int j = 0; j < n; j++) 133 | { 134 | sum2[i][j] = sum2[i][j] + d[i][j]; 135 | } 136 | 137 | count = n; 138 | count = count - 2; 139 | 140 | // 处理成可达矩阵 141 | while (count != 0) 142 | { 143 | 144 | for (int i = 0; i < n; i++) 145 | for (int j = 0; j < n; j++) 146 | for (int z = 0; z < n; z++) 147 | { 148 | e[i][j] += d[i][z] * a[z][j]; 149 | } 150 | count = count - 1; 151 | 152 | for (int i = 0; i < n; i++) 153 | for (int j = 0; j < n; j++) 154 | { 155 | sum2[i][j] = sum2[i][j] + e[i][j]; 156 | } 157 | 158 | memcpy(d, e, sizeof(e)); 159 | memset(e, 0, sizeof(e)); 160 | } 161 | 162 | for (int i = 0; i < n; i++) 163 | for (int j = 0; j < n; j++) 164 | { 165 | if (sum2[i][j] != 0) 166 | sum2[i][j] = 1; // 此时矩阵为可达矩阵 167 | } 168 | 169 | for (int i = 0; i < n; i++) 170 | for (int j = 0; j < n; j++) 171 | { 172 | if (i != j) 173 | { 174 | if (sum2[i][j] != 1) 175 | flag3 = 0; // 不是弱连通 176 | } 177 | } 178 | 179 | if (flag3 != 0) 180 | flag3 = 1; 181 | } 182 | 183 | if (flag1 == 1) 184 | cout << "A" << endl; 185 | else if (flag1 == 0 && flag2 == 1) 186 | cout << "B" << endl; 187 | else if (flag1 == 0 && flag2 == 0 && flag3 == 1) 188 | cout << "C" << endl; 189 | // else if(flag1==0&&flag2==0&&flag3==0) 190 | // cout<<"该图是不连通的"; 191 | return 0; 192 | } --------------------------------------------------------------------------------