日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

高斯消元习题

發(fā)布時間:2023/12/20 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 高斯消元习题 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

高斯消元

    • 概念
    • 浮點數(shù)模板
      • P3389 【模板】高斯消元法
    • 異或方程組
      • 模板
      • 開關(guān)問題 POJ - 1830
      • EXTENDED LIGHTS OUT

概念

  • 自由變元:取非零行的首非零元所在列對應(yīng)的變元為約束變元,其余變元取作自由變元
    比如 x1+x2+x3=3x_1+x_2+x_3=3x1?+x2?+x3?=3 ,這個式子的自由變元為 2 ,不確定變元為 3。因為這個式子中,當兩個變元確定之后,最后一個量也確定了。
  • 列主元消去法:取當前列 rowrowrow 以下的最大值所在行與 rowrowrow 所在行交換,這樣可以將較大的數(shù)放在第row列,即除數(shù)的位置,從而減小誤差

浮點數(shù)模板

int gauss(double a[][maxn],int n,int m) {for(int row=1,col=1; row<=n&&col<=m; ++row,++col){int maxrow=row;for(int i=row+1; i<=n; ++i)if(fabs(a[i][col])>fabs(a[row][col])) maxrow=i;if(maxrow!=row){for(int i=col; i<=m+1; ++i)swap(a[row][i],a[maxrow][i]);}//if(a[row][col]==0) return -1;//存在自由變元for(int i=row+1; i<=n; ++i){double tmp=a[i][col]/a[row][col];for(int j=col; j<=m+1; ++j)a[i][j]-=a[row][j]*tmp;}}for(int i=m; i>=1; --i){double res=a[i][m+1];for(int j=i+1; j<=m; ++j)res-=a[i][j]*x[j];x[i]=res/a[i][i];}return 0; }

P3389 【模板】高斯消元法

鏈接:https://www.luogu.com.cn/problem/P3389

#include <bits/stdc++.h> #define ll long long using namespace std; const int maxn=110;int n; double a[maxn][maxn]; double x[maxn];int gauss(double a[][maxn],int n,int m) {for(int row=1,col=1;row<=n&&col<=m;++row,++col){int maxrow=row;for(int i=row+1;i<=n;++i)if(abs(a[i][col])>abs(a[row][col])) maxrow=i;if(maxrow!=row){for(int i=col;i<=m+1;++i)swap(a[row][i],a[maxrow][i]);}if(a[row][col]==0) return -1;//存在自由變元for(int i=row+1;i<=n;++i){double tmp=a[i][col]/a[row][col];for(int j=col;j<=m+1;++j)a[i][j]-=a[row][j]*tmp;}} for(int i=m;i>=1;--i){double res=a[i][m+1];for(int j=i+1;j<=m;++j)res-=a[i][j]*x[j];x[i]=res/a[i][i];}return 0; }int main() { scanf("%d",&n);for(int i=1;i<=n;++i)for(int j=1;j<=n+1;++j)scanf("%lf",&a[i][j]);int res=gauss(a,n,n);if(res==-1) puts("No Solution");else{for(int i=1;i<=n;++i)printf("%.2lf\n",x[i]);}return 0; }

異或方程組

模板

int x[maxn]; int gauss(int a[][maxn],int n,int m) {int row,col;for(row=1,col=1; row<=n&&col<=m; ++row,++col){int maxrow=row;for(int i=row+1; i<=n; ++i)if(abs(a[i][col])>abs(a[row][col])) maxrow=i;if(maxrow!=row){for(int i=col; i<=m+1; ++i)swap(a[row][i],a[maxrow][i]);}if(a[row][col]==0){row--;continue;}for(int i=row+1; i<=n; ++i){if(a[i][col]!=0){for(int j=col; j<=m+1; ++j)a[i][j]^=a[row][j];}}}for(int i=row; i<=n; ++i)if(a[i][col]!=0) return -1;//存在無解的情況 if(row<m+1) return m-row+1;//返回自由變元的數(shù)量 for(int i=m; i>=1; --i){int res=a[i][m+1];for(int j=i+1; j<=m; ++j)if(a[i][j]!=0) res^=(a[i][j]&&x[j]);//&&替代了 *x[i]=(res&&a[i][i]);} }

開關(guān)問題 POJ - 1830

鏈接:http://poj.org/problem?id=1830

題意:給定 n 盞燈的初始狀態(tài)和最終狀態(tài),每次開關(guān)一盞燈都會引起相關(guān)的燈的變化,問有多少種方案從初始狀態(tài)到達最終狀態(tài)

思路:高斯消元,第 i 行表示第 i 盞燈受 1 ~ n 個開關(guān)的影響情況。

  • 比如, 1 0 1 1 1 表示當前燈受 x1,x3,x4x_1,x_3,x_4x1?,x3?,x4? 三盞燈的影響,并且累積狀態(tài)發(fā)生了改變
  • 最終答案就是求自由變元的個數(shù) xxx2x2^x2x 就是答案
#include <cstdio> #include <cmath> #include <algorithm> #include <cstring> #define ll long long using namespace std; const int maxn=35;int gauss(int a[][maxn],int n,int m) {int row,col;for(row=1,col=1; row<=n&&col<=m; ++row,++col){int maxrow=row;for(int i=row+1; i<=n; ++i)if(abs(a[i][col])>abs(a[row][col])) maxrow=i;if(maxrow!=row){for(int i=col; i<=m+1; ++i)swap(a[row][i],a[maxrow][i]);}if(a[row][col]==0){row--;continue;}for(int i=row+1; i<=n; ++i){if(a[i][col]!=0){for(int j=col; j<=m+1; ++j)a[i][j]^=a[row][j];}}}for(int i=row; i<=n; ++i)if(a[i][col]!=0) return -1;return m-row+1; } int t,n,s[maxn],e[maxn],a[maxn][maxn]; int main() {scanf("%d",&t);while(t--){scanf("%d",&n);for(int i=1; i<=n; ++i) scanf("%d",&s[i]);for(int i=1; i<=n; ++i) scanf("%d",&e[i]);memset(a,0,sizeof(a));int u,v;while(scanf("%d%d",&u,&v)&&(u||v)) a[v][u]=1;for(int i=1; i<=n; ++i) a[i][i]=1;for(int i=1; i<=n; ++i) a[i][n+1]=s[i]^e[i];int res=gauss(a,n,n);if(res==-1) puts("Oh,it's impossible~!!");else printf("%d\n",(1<<res));}return 0; }

EXTENDED LIGHTS OUT

鏈接:http://poj.org/problem?id=1222

題意:給出一個 5×65 \times 65×6 的 01 矩陣,每次選擇一個位置 (i,j)(i,j)(ij) 會翻轉(zhuǎn)與它相鄰的 4 個點和它自己,請你輸出一種方案,使得矩陣全部翻轉(zhuǎn)為 0

思路: 類比上一題,30盞燈,每 i 行表示第 i 盞燈受到的其他燈的影響情況,最后一個值 val 表示是否需要改變。

#include <cstdio> #include <cmath> #include <algorithm> #include <cstring> #define ll long long using namespace std; const int maxn=35;int x[maxn]; int gauss(int a[][maxn],int n,int m) {int row,col;for(row=1,col=1; row<=n&&col<=m; ++row,++col){int maxrow=row;for(int i=row+1; i<=n; ++i)if(abs(a[i][col])>abs(a[row][col])) maxrow=i;if(maxrow!=row){for(int i=col; i<=m+1; ++i)swap(a[row][i],a[maxrow][i]);}if(a[row][col]==0){row--;continue;}for(int i=row+1; i<=n; ++i){if(a[i][col]!=0){for(int j=col; j<=m+1; ++j)a[i][j]^=a[row][j];}}}for(int i=row; i<=n; ++i)if(a[i][col]!=0) return -1;//存在無解的情況 if(row<m+1) return m-row+1;//返回自由變元的數(shù)量 for(int i=m; i>=1; --i){int res=a[i][m+1];for(int j=i+1; j<=m; ++j)if(a[i][j]!=0) res^=(a[i][j]&&x[j]);//&&替代了 *x[i]=(res&&a[i][i]);} } int t,a[maxn][maxn]; int main() {int Case=0;scanf("%d",&t);while(t--){memset(a,0,sizeof(a));memset(x,0,sizeof(x));for(int i=1; i<=30; ++i) scanf("%d",&a[i][31]);for(int i=1; i<=5; ++i){for(int j=1; j<=6; ++j){int col=(i-1)*6+j;a[col][col]=1;if(i>1) a[(i-2)*6+j][col]=1;if(i<5) a[i*6+j][col]=1;if(j>1) a[(i-1)*6+j-1][col]=1;if(j<6) a[(i-1)*6+j+1][col]=1;}}gauss(a,30,30);printf("PUZZLE #%d\n",++Case);for(int i=1; i<=30; ++i)printf("%d%c",x[i],i%6==0?'\n':' ');}return 0; }

枚舉寫法

#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> using namespace std; int t,x; int origin[10],ans[10],light[10]; void flip(int &x,int pos) {x^=(1<<pos-1); } int main() {scanf("%d",&t);int Cas=0;while(t--){memset(origin,0,sizeof(origin));for(int i=1;i<=5;++i){for(int j=1;j<=6;++j){scanf("%d",&x);if(x==1) origin[i]|=(1<<j-1); } }for(int i=0;i<64;++i){memcpy(light,origin,sizeof(origin));int choose=i;for(int j=1;j<=5;++j){ans[j]=choose;for(int k=1;k<=6;++k){if(choose>>k-1&1){if(k>1) flip(light[j],k-1);flip(light[j],k);if(k<6) flip(light[j],k+1);}}if(j<5)light[j+1]^=choose; choose=light[j];}if(light[5]==0){printf("PUZZLE #%d\n",++Cas);for(int j=1;j<=5;++j)for(int k=1;k<=6;++k)printf("%d%c",ans[j]>>k-1&1,k==6?'\n':' ');break;}} }return 0; }

總結(jié)

以上是生活随笔為你收集整理的高斯消元习题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。