洛谷 P3389 【模板】高斯消元法 × 洛谷 P2455 [SDOI2006]线性方程组

本文介绍了如何使用高斯消元法解决洛谷P3389和P2455线性方程组问题。作者通过十几小时的学习和实践,形成了自己的代码模板,虽然部分细节尚存疑惑,但已实现了解决函数gauss_elim(),该函数根据返回值判断解的状态:唯一解、格式错误、无数解或无解。

一、传送门

https://www.luogu.com.cn/problem/P3389
https://www.luogu.com.cn/problem/P2455

二、代码

日……两道题合起来搞了我十几个小时,最后把我气得从别人的 AC 代码开始再一句一句改成适配自己模板的同义的语句。
有些细节还是不太懂,暂时先把模板放上来。以后有时间再出详解。
————————————————————————————————————————————————————
高斯消元函数 gauss_elim() 的返回值:
0,唯一解;1,格式错(矩阵不是n行×(n+1)列);2,无数解;3,无解。
————————————————————————————————————————————————————
P3389:

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstdint>
#include<vector>
#pragma warning(disable:4996)
using namespace std;
template<class _Ty = double> class matrix {
private:
	vector<vector<_Ty>> m; size_t row, col, _size;
public:
	matrix() { row = col = _size = 0; }
	matrix(const size_t& r, const size_t& c) { init(r, c); }
	virtual ~matrix() { del(); }
	void clear() { fill(m[0], m[0] + _size, 0); }
	void del() { m.resize(0); }
	void init(const size_t& r, const size_t& c) {
		row = r; col = c; _size = row * col; m.resize(r); for (size_t i = 0; i != r; ++i)m[i].resize(c);
	}
	void resize(const size_t& r, const size_t& c) const { del(); init(r, c); }
	void resize_directly(const size_t& r, const size_t& c) { row = r; col = c; _size = row * col; }
	size_t _row() const { return row; }
	size_t _col() const { return col; }
	size_t size() const { return _size; }
	void row_mul(const size_t& row, const _Ty& val) {
		for (size_t i = 0; i != col; ++i)m[row][i] *= val;
	}
	void row_mul_add_to(const size_t& rs, const _Ty& val, const size_t& rd) {
		for (size_t i = 0; i != col; ++i)m[rd][i] += m[rs][i] * val;
	}
	void interchange(const size_t& r1, const size_t& r2) { swap(m[r1], m[r2]); }
	vector<_Ty>& operator[](const size_t& r) { return m.at(r); }
	const vector<_Ty>& operator[](const size_t& r) const { return m.at(r); }
};
template<class _Ty = double> inline unsigned gauss_elim(matrix<_Ty>& a, _Ty* const x) {
	_Ty y, b; size_t n = a._row(), p, c; bool inf = false;
	for (size_t i = 0; i < n; ++i) {
		p = i; b = abs(a[p][i]);
		for (size_t j = i + 1; j < n; ++j)if (abs(a[j][i]) > b) { p = j; }
		if (p != i)a.interchange(p, i);
		if (a[i][i] == 0)continue;
		b = 1 / a[i][i];
		for (size_t j = 0; j < i; ++j)a.row_mul_add_to(i, -a[j][i] * b, j);
		for (size_t j = i + 1; j < n; ++j)a.row_mul_add_to(i, -a[j][i] * b, j);
	}
	for (size_t i = 0; i < n; ++i) {
		c = 0;
		for (size_t j = 0; j <= n; ++j) { if (a[i][j] == 0)++c; }
		if (c == n && a[i][n]) { return 3; }
		if (c == a._col()) { inf = true; }
	}
	if (inf)return 2;
	for (size_t i = n - 1; i != SIZE_MAX; --i) {
		y = a[i][n]; for (size_t j = n - 1; j > i; --j) { y -= a[i][j] * x[j]; }
		x[i] = y / a[i][i];
	}
	return 0;
}
matrix<double> m; size_t n; double x[100];
int main() {
	scanf("%llu", &n); m.init(n, n + 1);
	for (size_t i = 0; i < n; ++i)
		for (size_t j = 0; j <= n; ++j)scanf("%lf", &m[i][j]);
	if (!gauss_elim(m, x))for (size_t i = 0; i < n; ++i)printf("%.2lf\n", x[i]);
	else puts("No Solution");
	return 0;
}

P2455:

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstdint>
#include<vector>
#pragma warning(disable:4996)
using namespace std;
template<class _Ty = double> class matrix {
private:
	vector<vector<_Ty>> m; size_t row, col, _size;
public:
	matrix() { row = col = _size = 0; }
	matrix(const size_t& r, const size_t& c) { init(r, c); }
	virtual ~matrix() { del(); }
	void clear() { fill(m[0], m[0] + _size, 0); }
	void del() { m.resize(0); }
	void init(const size_t& r, const size_t& c) {
		row = r; col = c; _size = row * col; m.resize(r); for (size_t i = 0; i != r; ++i)m[i].resize(c);
	}
	void resize(const size_t& r, const size_t& c) const { del(); init(r, c); }
	void resize_directly(const size_t& r, const size_t& c) { row = r; col = c; _size = row * col; }
	size_t _row() const { return row; }
	size_t _col() const { return col; }
	size_t size() const { return _size; }
	void row_mul(const size_t& row, const _Ty& val) { for (size_t i = 0; i != col; ++i)m[row][i] *= val; }
	void row_mul_add_to(const size_t& rs, const _Ty& val, const size_t& rd) {
		for (size_t i = 0; i != col; ++i)m[rd][i] += m[rs][i] * val;
	}
	void interchange(const size_t& r1, const size_t& r2) { swap(m[r1], m[r2]); }
	vector<_Ty>& operator[](const size_t& r) { return m.at(r); }
	const vector<_Ty>& operator[](const size_t& r) const { return m.at(r); }
};
template<class _Ty = double> inline unsigned gauss_elim(matrix<_Ty>& a, _Ty* const x) {
	_Ty y, b; size_t n = a._row(), p, c; bool inf = false;
    for (size_t i = 0; i < n; ++i) {
		p = i; b = abs(a[p][i]);
		for (size_t j = i + 1; j < n; ++j)if (abs(a[j][i]) > b) { p = j; }
		if (p != i)a.interchange(p, i);
		if (a[i][i] == 0)continue;
		b = 1 / a[i][i];
        for (size_t j = 0; j < i; ++j)a.row_mul_add_to(i, -a[j][i] * b, j);
        for (size_t j = i + 1; j < n; ++j)a.row_mul_add_to(i, -a[j][i] * b, j);
    }
    for (size_t i = 0; i < n; ++i) {
        c = 0;
        for (size_t j = 0; j <= n; ++j) { if (a[i][j] == 0)++c; }
		if (c == n && a[i][n]) { return 3; }
		if (c == a._col()) { inf = true; }
    }
    if (inf)return 2;
	for (size_t i = n - 1; i != SIZE_MAX; --i) {
		y = a[i][n]; for (size_t j = n - 1; j > i; --j) { y -= a[i][j] * x[j]; }
		x[i] = y / a[i][i];
	}
	return 0;
}
matrix<double> m; size_t n; double x[50];
int main() {
	scanf("%llu", &n); m.init(n, n + 1);
	for (size_t i = 0; i < n; ++i)
		for (size_t j = 0; j <= n; ++j)scanf("%lf", &m[i][j]);
	switch (gauss_elim(m, x)) {
	case 3:puts("-1"); return 0;
	case 2:puts("0"); return 0;
	default:for (size_t i = 0; i < n; ++i)printf("x%llu=%.2lf\n", i + 1, x[i]); return 0;
	}
}
内容概要:本文档是一份关于交换路由配置的学习笔记,系统地介绍了网络设备的远程管理、交换机与路由器的核心配置技术。内容涵盖Telnet、SSH、Console三种远程控制方式的配置方法;详细讲解了VLAN划分原理及Access、Trunk、Hybrid端口的工作机制,以及端口镜像、端口汇聚、端口隔离等交换技术;深入解析了STP、MSTP、RSTP生成树协议的作用与配置步骤;在路由部分,涵盖了IP地址配置、DHCP服务部署(接口池与全局池)、NAT转换(静态与动态)、静态路由、RIP与OSPF动态路由协议的配置,并介绍了策略路由和ACL访问控制列表的应用;最后简要说明了华为防火墙的安全区域划分与基本安全策略配置。; 适合人群:具备一定网络基础知识,从事网络工程、运维或相关技术岗位1-3年的技术人员,以及准备参加HCIA/CCNA等认证考试的学习者。; 使用场景及目标:①掌握企业网络中常见的交换与路由配置技能,提升实际操作能力;②理解VLAN、STP、OSPF、NAT、ACL等核心技术原理并能独立完成中小型网络搭建与调试;③通过命令示例熟悉华为设备CLI配置逻辑,为项目实施和故障排查提供参考。; 阅读建议:此笔记以实用配置为主,建议结合模拟器(如eNSP或Packet Tracer)动手实践每一条命令,对照拓扑理解数据流向,重点关注VLAN间通信、路由选择机制、安全策略控制等关键环节,并注意不同设备型号间的命令差异。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值