0
点赞
收藏
分享

微信扫一扫

蓝桥杯算法入门_17 (数论竞赛思想)

老北京的热干面 2022-03-18 阅读 57

目录

#include <iostream>
using namespace std;
#include<algorithm>


int gcd(int a,int b) {
	if(b == 0) {
		return a;
	}
	return gcd(b,a%b);
}

int test_01() {
	int n,m;
	cin >> n >> m;
	int GCD = gcd(n,m);
	cout << GCD << endl;
	cout << n / GCD * m << endl;  //!!!!  先除 再乘 防止数过大溢出 !!!!   得到最小公倍数
	return 0;
}

质数筛选

#include<cstring>  // memset

bool is_prime[100];
int test_02() {
	//memset(is_prime,1,sizeof(is_prime)); //让每一位都是1 即每一位都是true
	for(int i = 2; i < 100; i++) {
		is_prime[i] = true;
	}
	for(int i = 2; i * i < 100; i++) {
		if(is_prime[i]) { //如果i是质数 (没有被其他数筛过)
			for(int j = i*i; j < 100; j += i) { // 从i*i开始筛 ,遍历i的倍数
				is_prime[j] = false; //标记为不是素数
			}
		}
	}
	for(int i = 2; i < 100; i++) {
		if(is_prime[i]) {
			cout << i <<endl;  //输出 100以内 的质数
		}
	}
	return 0;
}

欧拉函数 – 求互质数个数

int test_03() {
	int n;
	cin >> n;
	int res = n;
	for(int i = 2; i * i <= n; i++) {  //遍历到 根号n
		if(n % i ==0) {//找出最小的一个质因数
			res = res / i * (i - 1);  // 即 * ( i-1 / i )  但是为了不溢出 ,就先除
			while(n % i == 0) {
				n /= i;
			}
		}
	} //条件 n > 1是因为公式f(n) = n * (1 - 1/p1) * (1 - 1/p2) ... (1 - 1/pn) , n!=1说明还有没用过的 互质数)
	if(n > 1) {//最后再来判断有没有一个超过 根号n的质因数 (因为乘积不超过本身,所有最多仅有一个)
		res = res / n * (n - 1);  //说明还有最后一个 大于根号n的互质数
	}
	cout << res << endl;  //与n互质的数 个数
	return 0;
}

区间预处理的欧拉函数 ( n个数 )

int phi[10001];
int test_04() {
	int n;
	cin >> n;
	for(int i = 1; i <= n; i++) {//初始化欧拉函数值为 本身 (此时的值是不正确的欧拉函数值)
		phi[i] = i;
	}
	for(int i = 2; i <= n; i++) {
		if(phi[i] == i) {//如果从2 - n循环 这个数的欧拉函数值还是本身 说明这个数是质数 !!! 但和phi[i] 互质的数的个数 是i-1 !!!
			for(int j = i; j <= n; j += i) { //i的倍数找质数
				phi[j] = phi[j] / i * (i - 1);
			}
		}
	}
	for(int i = 1; i <= n; i++) {
		cout << "phi(" << i << ") =  " << phi[i] << endl;
	}
	return 0;
}

矩阵加减 (线性代数 – 公式)

struct matrix {
	int a[100][100];
	int n,m;
};

matrix matrix_mul(matrix A,matrix B) {
	matrix ret; //返回新矩阵
	ret.n = A.n;//新矩阵的行列
	ret.m = B.m;
	for(int i = 0; i < ret.n; i++) {
		for(int j = 0; j < ret.m; j++) {
			ret.a[i][j] = 0;
		}
	}
	for(int i = 0; i < ret.n; i++) { //前两层遍历新矩阵的每一个位置 ,中间第三次计算每个位置的值
		for(int j = 0; j < ret.m; j++) {
			for(int k = 0; k < A.m; k++) { //公式 : 对应行 * 对应列 ,当然也可以用 B.n ,但公式下标换成列一下
				ret.a[i][j] += A.a[i][k] * B.a[k][j];
			}
		}
	}
	return ret; 
}

int test_05() {
	//录入数据
	matrix A,B;
	cin >> A.n >> A.m;
	for(int i = 0; i < A.n; i++) {
		for(int j = 0; j < A.m; j++) {
			cin >> A.a[i][j];
		}
	}
	cin >> B.n >> B.m;
	for(int i = 0; i < B.n; i++) {
		for(int j = 0; j < B.m; j++) {
			cin >> B.a[i][j];
		}
	}
	if(A.m != B.n) {
		cout << "No" << endl; //不符合运算规则
	} else {
		matrix C = matrix_mul(A,B);
		for(int i = 0; i < C.n; i++) { //输出新矩阵
			for(int j = 0; j < C.m; j++) {
				if(j != C.m - 1) { //行末空格
					cout <<	C.a[i][j] << " ";
				} else {
					cout <<	C.a[i][j] << endl;
				}
			}
		}
	}
	return 0;
}


int main() {
	test_05();

	return 0;


}




举报

相关推荐

0 条评论