【题解】[Swerc2008]First Knight

sol:
如果你把满足上述条件的所有等式画成一个矩阵,你会发现 所有非零元素(除了最后一列常数项)位于距离对角线 ±d 的范围内。对这样的矩阵进行高斯消元,称作带状矩阵的高斯消元。

在这里插入图片描述
如上图,带宽为 2 ,那么每次就是一个 2 * 2 矩阵的高斯消元。

上述消元过程是 o ( n d 2 ) o(nd^2) o(nd2) 的 : o(n) 枚举 i 行,对于用每一行给下方 d 行消元,每一行的消元只会枚举不超过 d 个未知数。

从本题上看,就是一个为 2n+1 ,宽为 2m+1 的带宽矩阵。

当然这种做法并没有考虑到有非常多的 0,如果进一步压缩(只遍历初始不为 0 的位置)会更快。

本题时间复杂度 o ( ( n m ) 2 ) o((nm)^2) o((nm)2)

#include <bits/stdc++.h> #define db double #define eps 1e-18 using namespace std; const int N = 45 * 45; int n, m; int dx[4] = { 1, 0, -1, 0 }, dy[4] = { 0, 1, 0, -1 }; db p[4][N][N], A[N][N], ans[N]; int has(int i, int j) { return (i - 1) * m + j; } void gauss() { int r, c; for (r = 1, c = 1; r < n * m && c <= n * m; r++, c++) { int p = r; for (int i = r; i < n * m; i++) { if (fabs(A[i][c]) > fabs(A[p][c])) p = i; } //思考一下带宽矩阵消元的适合需不需要交换这两行? swap(A[r], A[p]); for (int i = r + 1; i < n * m && i <= r + 2 * n; i++) { if (fabs(A[i][c]) > eps) { db tmp = A[i][c] / A[r][c]; for (int j = c; j < n * m && j <= c + 2 * m; j++) { A[i][j] -= A[r][j] * tmp; } A[i][n * m] -= A[r][n * m] * tmp; } } } for (int i = n * m - 1; i >= 0; i--) { for (int j = n * m - 1; j > i; j--) { if (fabs(A[i][j]) > eps) { A[i][n * m] -= A[i][j] * ans[j]; } } ans[i] = A[i][n * m] / A[i][i]; } } int main() { while (scanf("%d%d", &n, &m)) { for (int k = 0; k < 4; k++) { for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { scanf("%lf", &p[k][i][j]); } } } for (int i = 1; i < n * m; i++) { for (int j = 1; j <= n * m; j++) { A[i][j] = 0; } } for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { if (i == n && j == m) continue; A[has(i, j)][has(i, j)] = 1; A[has(i, j)][n * m] = 1; for (int k = 0; k < 4; k++) { int ti = i + dx[k], tj = j + dy[k]; if (ti < 1 || ti > n || tj < 1 || tj > m) continue; if (ti == n && tj == m) continue; A[has(i, j)][has(ti, tj)] = -p[k][i][j]; } } } gauss(); printf("%.10f\n", ans[1]); } }

__EOF__

本文作者仰望星空的蚂蚁
本文链接https://www.cnblogs.com/cqbzly/p/17530220.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   仰望星空的蚂蚁  阅读(5)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
点击右上角即可分享
微信分享提示