因为该偏序集中任意两个元素的最小公倍数和最大公约数就是这两个元素的最小商界和最大下界因此它是格
cal_factor()函数计算因子,用1到n/2(一个正整数n除了它本身的其他因子显然是小于等于n/2的)的for循环通过判断余数是否为0来找到n的所有因子并存在factor数组中输出
cal_matrix()函数计算关系矩阵,先将关系矩阵数组matrix初始化为0,
通过判断各因子间的整除关系给关系矩阵赋值,若factor[j]%factor[i]==0则说明factor[j]可以整除factor[i],则matrix[i][j]值赋为1
cover()函数计算盖住集,若matrix中的三个元素存在传递关系i-j,j-k则i-k显然不是盖住集中的元素,将matrix[i][k]的值赋为0
gcd()函数计算两个数的最大公约数,辗转相除法
solve() 函数判断是否为有补格,若除了 1 和这个数 n 本身的其他因子都能找到一个因子使得与其的最大公约数为 1 最小公倍数为 n ,则其为有补格,有一个元素找不到,则不是有补格,直接退出
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
int n, cnt;
int factor[50];
int matrix[20][20];
void cal_factor() //计算数字的因子
{
cout << "因子为: ";
for(int i = 1; i <= n / 2; i++)
{
if(n % i == 0)
{
factor[cnt++] = i;
cout << i << ",";
}
}
factor[cnt] = n;
cout << factor[cnt] << endl;
}
void cal_matrix() //计算关系矩阵
{
memset(matrix, 0, sizeof(matrix));
for(int i = 0; i <= cnt; i++)
for(int j = 0; j <= cnt; j++)
if(factor[j] % factor[i] == 0)
matrix[i][j] = 1;
}
void cover() //盖住集
{
cal_matrix();
for(int i = 0; i <= cnt; i++)
{
for(int j = 0; j <= cnt; j++)
{
for(int k = 0; k <= cnt; k++)
{
matrix[k][k] = 0;
if(matrix[i][j] && matrix[j][k])
matrix[i][k] = 0;
}
}
}
cout << "盖住集为: {";
for(i = 0; i <= cnt; i++)
for(int j = 0; j <= cnt; j++)
if(matrix[i][j])
cout << " <" << factor[i] << "," << factor[j] << ">";
cout << " }" << endl;
}
int gcd(int x, int y) //最大公约数
{
int r = 1;
while(r != 0)
{
r = x % y;
x = y;
y = r;
}
return x;
}
void solve() //判断是否为有补格
{
bool flag;
int Gcd, Lcm;
for(int i = 1; i < cnt; i++)
{
flag = false;
for(int j = 1; j < cnt; j++)
{
if(i == j)
continue;
Gcd = gcd(factor[i], factor[j]);
Lcm = factor[i] / Gcd * factor[j];
if(Gcd == factor[0] && Lcm == factor[cnt])
{
flag = true;
break;
}
if(!flag)
{
cout << "该格不是有补格!" << endl;
return;
}
}
}
cout << "该格是有补格!" << endl;
return;
}
int main()
{
cnt = 0;
cout << "请输入一个正整数: ";
cin >> n;
cal_factor();
cover();
solve();
return 0;
}