讀入:(轉自:chuyds's Bloghtml
法一:node
while(scanf("%d",&a)!=EOF)
法二:ios
while(cin>>n)
法三:c++
while(~scanf("%d",&a))
1.最小生成樹算法
只會Kruskal w數組
#include<bits/stdc++.h> using namespace std; inline int read(){ int ans=0; char last=' ',ch=getchar(); while(ch>'9'||ch<'0') last=ch,ch=getchar(); while(ch>='0'&&ch<='9') ans=(ans<<1)+(ans<<3)+ch-'0',ch=getchar(); if(last=='-') ans=-ans; return ans; } int n,m; int fa[5010]; struct node{ int u,v,w; }e[200010]; bool cmp(node a,node b) { return a.w<b.w; } int find(int x){ if(fa[x]!=x) fa[x]=find(fa[x]); return fa[x]; } int main(){ n=read(); m=read(); for(int i=1;i<=m;i++) { e[i].u=read(); e[i].v=read(); e[i].w=read(); } sort(e+1,e+m+1,cmp); int ans=0; for(int i=1;i<=n;i++) fa[i]=i; for(int i=1,u,v,fu,fv;i<=m;i++) { u=e[i].u; v=e[i].v; fu=find(u); fv=find(v); if(fu==fv) continue; fa[fu]=fv; ans+=e[i].w; } printf("%d",ans); return 0; }
2.單源最短路函數
dijkstraui
#include<bits/stdc++.h> #define pa pair<int,int> using namespace std; inline int read(){ int ans=0; char last=' ',ch=getchar(); while(ch>'9'||ch<'0') last=ch,ch=getchar(); while(ch>='0'&&ch<='9') ans=(ans<<1)+(ans<<3)+ch-'0',ch=getchar(); if(last=='-') ans=-ans; return ans; } const int mxn=100010; int n,m,s; int head[mxn],ecnt; struct node { int to,dis,nxt; }e[mxn<<1]; void add(int from,int to,int dis){ ++ecnt; e[ecnt].nxt=head[from]; e[ecnt].to=to; e[ecnt].dis=dis; head[from]=ecnt; } int dis[mxn]; bool vis[mxn]; priority_queue<pa,vector<pa>,greater<pa> > q; void dij(int s){ dis[s]=0; q.push(make_pair(dis[s],s)); while(!q.empty()){ int u=q.top().second; q.pop(); if(vis[u]) continue; vis[u]=1; for(int i=head[u],v;i;i=e[i].nxt){ v=e[i].to; if(dis[v]>dis[u]+e[i].dis){ dis[v]=dis[u]+e[i].dis; q.push(make_pair(dis[v],v)); } } } } int main(){ n=read(); m=read(); s=read(); memset(dis,0x3f,sizeof(dis)); for(int i=1,u,v,w;i<=m;i++){ u=read(); v=read(); w=read(); add(u,v,w); } dij(s); for(int i=1;i<=n;i++) printf("%d ",dis[i]); return 0; }
spfaspa
#include<bits/stdc++.h> using namespace std; inline int read(){ int ans=0; char last=' ',ch=getchar(); while(ch>'9'||ch<'0') last=ch,ch=getchar(); while(ch>='0'&&ch<='9') ans=(ans<<1)+(ans<<3)+ch-'0',ch=getchar(); if(last=='-') ans=-ans; return ans; } const int mxn=100010; int n,m,s; int head[mxn],ecnt; struct node { int to,dis,nxt; }e[mxn<<3]; void add(int from,int to,int dis){ ++ecnt; e[ecnt].nxt=head[from]; e[ecnt].to=to; e[ecnt].dis=dis; head[from]=ecnt; } int dis[mxn]; bool vis[mxn]; queue<int> Q; void spfa(){ Q.push(s); for(int i=1;i<=n;i++) dis[i]=2147483647,vis[i]=0; vis[s]=1;dis[s]=0; while(!Q.empty()) { int u=Q.front(); Q.pop(); vis[u]=0; for(int i=head[u],v;i;i=e[i].nxt) { v=e[i].to; if(dis[v]>dis[u]+e[i].dis) { dis[v]=dis[u]+e[i].dis; if(!vis[v]) Q.push(v),vis[v]=1; } } } } int main(){ n=read(); m=read(); s=read(); for(int i=1,u,v,w;i<=m;i++){ u=read(); v=read(); w=read(); add(u,v,w); } spfa(); for(int i=1;i<=n;i++) printf("%d ",dis[i]); return 0; }
3.tarjancode
void tarjan(int u) { dfn[u]=low[u]=++tim; vis[u]=1; s[top++]=u; for(int i=head[u],v;i;i=e[i].nxt) { v=e[i].to; if(!dfn[v]) { tarjan(v); low[u]=min(low[v],low[u]); } else if(vis[v]) low[u]=min(dfn[v],low[u]); } if(dfn[u]==low[u]){ ++scc_cnt; while(s[top]!=u){ top--; vis[s[top]]=0; scc[s[top]]=scc_cnt; cnt[scc_cnt]++; } } }
4.kmp
#include<bits/stdc++.h> using namespace std; char a[mxn],b[mxn]; int lena,lenb; int p[mxn]; void ych(){ p[1]=0; int j=0; for(int i=1;i<lenb;i++) { while(j>0&&b[j+1]!=b[i+1]) j=p[j]; if(b[j+1]==b[i+1]) j++; p[i+1]=j; } } void kmp(){ int j=0; for(int i=0;i<lena;i++) { while(j>0&&b[j+1]!=a[i+1]) j=p[j]; if(b[j+1]==a[i+1]) j++; if(j==lenb) { printf("%d\n",i+1-lenb+1); j=p[j]; } } } int main(){ scanf("%s%s",a+1,b+1); lena=strlen(a+1); lenb=strlen(b+1); ych(); kmp(); return 0; }
trie樹:
#include<bits/stdc++.h> using namespace std; int n,m,tot=1; char word[55]; int trie[500011][27]; int vis[500011]; void insert(char *s,int rt) { for(int i=0;i<strlen(s);i++) { int x=s[i]-'0'; if(trie[rt][x]==0) trie[rt][x]=++tot; rt=trie[rt][x]; } vis[rt]=1; } int search(char *s,int rt) { for(int i=0;i<strlen(s);i++) { int x=s[i]-'0'; if(trie[rt][x]==0) return 0; rt=trie[rt][x]; } if(vis[rt]==0) return 0; if(vis[rt]==1) { vis[rt]=2; return 1; } if(vis[rt]==2) return 2; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%s",word); insert(word,1); } scanf("%d",&m); for(int i=1;i<=m;i++) { scanf("%s",word); int k=search(word,1); if(!k) printf("WRONG\n"); else { if(k==1) printf("OK\n"); else printf("REPEAT\n"); } } return 0; }
5.線性篩
#include<bits/stdc++.h> using namespace std; const int mxn=100010; int n; bool is[mxn]; int pri[mxn],cnt; int main(){ scanf("%d",&n); for(int i=2;i<=n;i++) { if(!is[i]) pri[++cnt]=i; for(int j=1;j<=cnt&&pri[j]*i<=n;j++) { is[i*pri[j]]=1; if(i%pri[j]==0) break; } } for(int i=1;i<=cnt;i++) cout<<pri[i]<<" "; return 0; }
6.求解同餘方程:
\[ 求解:ax\equiv c(mod\ \ b)\\ ax=by+c\\ 即求解ax+by=c(正負無所謂\\ 若方程有解,則:\\ c=k\times gcd(a,b) \ \ k\in N^*\\ 擴展歐幾里得定理求得的解爲ax+by=exgcd(a,b)\\ 若要求解ax+by=k\times exgcd(a,b)\\在求解ax+by=exgcd(a,b)基礎上,同乘k \\x,y的通解: x+=b/gcd(a,b),y-=a/gcd(a,b) \]
void exgcd(int a,int b,int &x,int &y) { if(b==0) {x=1;y=0;return a;} int g=exgcd(b,a%b,x,y); int t=x; x=y; y=t-a/b*x; return g; }
7.中國剩餘定理:
若\(a_1,a_2 \cdots\cdots a_n\)是兩兩互質的正整數,\(M= \prod_{i=1}^na_i,M_i=M/a_i\),\(t_i\)是線性同餘方程\(M_it_i≡1(\mod a_i)\)的一個解。對於任意的n個整數\(b_1,b_2 \cdots \cdots b_n\),則同餘方程組:
\[ \begin{cases} x\equiv b_1 (\mod a_1)\\ x\equiv b_2 (\mod a_2)\\ x\equiv b_3 (\mod a_3)\\ ……\\ x\equiv b_n (\mod a_n)\\ \end{cases} \]
有整數解,方程組的解爲\(x=b_1M_1t_1+b_2M_2t_2+ \cdots \cdots +b_nM_nt_n\).而且在%M意義下有惟一解
#include<bits/stdc++.h> #define ll long long using namespace std; int n; ll M,x,y,ans; ll a[15],b[15]; ll exgcd(ll a,ll b,ll &x,ll &y) { if(b==0) {x=1;y=0;return a;}; ll g=exgcd(b,a%b,x,y); ll t=x; x=y; y=t-a/b*x; return g; } void solve(int k) { ll M_=M/a[k]; exgcd(M_,a[k],x,y); ans=(ans+((x*M_)%M*b[k])%M+M)%M; } int main() { scanf("%d",&n); M=1; for(int i=1;i<=n;i++) scanf("%lld%lld",&a[i],&b[i]),M*=a[i]; for(int i=1;i<=n;i++) solve(i); printf("%lld",ans); return 0; }
8.樹狀數組:
#include<bits/stdc++.h> #define ll long long using namespace std; ll n,m; ll c[1000000]; ll lowbit(ll x) { return x&(-x);} void add(ll x,ll ad) { while(x<=n) { c[x]+=ad; x+=lowbit(x); } } ll sum(ll x) { ll S=0; while(x>0) { S+=c[x]; x-=lowbit(x); } return S; } int main() { scanf("%lld%lld",&n,&m); for(int i=1,a;i<=n;i++) { scanf("%d",&a); add(i,a); } for(int i=1,opt,x,y;i<=m;i++) { scanf("%d%d%d",&opt,&x,&y); if(opt==1) add(x,y); else printf("%lld\n",sum(y)-sum(x-1)); } return 0; }
9.線段樹:
#include<bits/stdc++.h> #define ll long long using namespace std; const int mxn=100010; int n,m; ll a[mxn]; ll t[mxn<<2],tag[mxn<<2]; void build(int k,int l,int r) { if(l==r) { t[k]=a[l]; return; } int mid=(l+r)>>1; build(k<<1,l,mid); build(k<<1|1,mid+1,r); t[k]=t[k<<1]+t[k<<1|1]; } void pushdown(int k,int l,int r) { int mid=(l+r)>>1; if(!tag[k]) return; tag[k<<1]+=tag[k]; tag[k<<1|1]+=tag[k]; t[k<<1]+=(mid-l+1)*tag[k]; t[k<<1|1]+=(r-mid)*tag[k]; tag[k]=0; } void modify(int k,int l,int r,int x,int y,int q) { if(x<=l&&r<=y) { tag[k]+=q; t[k]+=(r-l+1)*q; return; } pushdown(k,l,r); int mid=(l+r)>>1; if(x<=mid) modify(k<<1,l,mid,x,y,q); if(y>mid) modify(k<<1|1,mid+1,r,x,y,q); t[k]=t[k<<1]+t[k<<1|1]; } ll query(int k,int l,int r,int x,int y) { if(x<=l&&r<=y) return t[k]; pushdown(k,l,r); int mid=(l+r)>>1; ll rtn=0; if(x<=mid) rtn+=query(k<<1,l,mid,x,y); if(y>mid) rtn+=query(k<<1|1,mid+1,r,x,y); return rtn; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); build(1,1,n); for(int i=1,opt,x,y,k;i<=m;i++) { scanf("%d%d%d",&opt,&x,&y); if(opt==1) { scanf("%d",&k); modify(1,1,n,x,y,k); } else printf("%lld\n",query(1,1,n,x,y)); } }
10.LCA:
(樹剖
#include<bits/stdc++.h> using namespace std; const int mxn=500010; int n,m,S; struct node { int to,nxt; }e[mxn<<1]; int ecnt,head[mxn]; void add(int from,int to) { ++ecnt; e[ecnt].to=to; e[ecnt].nxt=head[from]; head[from]=ecnt; } int fa[mxn],siz[mxn],dep[mxn],son[mxn]; void dfs1(int u,int f) { fa[u]=f; siz[u]=1; dep[u]=dep[f]+1; int maxn=-1; for(int i=head[u],v;i;i=e[i].nxt) { v=e[i].to; if(v==f) continue; dfs1(v,u); siz[u]+=siz[v]; if(siz[v]>maxn) { maxn=siz[v]; son[u]=v; } } } int top[mxn]; void dfs2(int u,int f) { if(son[f]==u) top[u]=top[f]; else top[u]=u; if(son[u]) dfs2(son[u],u); for(int i=head[u],v;i;i=e[i].nxt) { v=e[i].to; if(v==f||v==son[u]) continue; dfs2(v,u); } } int getlca(int x,int y) { while(top[x]!=top[y]) { if(dep[top[x]]>dep[top[y]]) x=fa[top[x]]; else y=fa[top[y]]; } if(dep[x]>dep[y]) return y; else return x; } int main() { scanf("%d%d%d",&n,&m,&S); for(int i=1,x,y;i<n;i++) { scanf("%d%d",&x,&y); add(x,y); add(y,x); } dfs1(S,0); dfs2(S,0); for(int i=1,a,b,lca;i<=m;i++) { scanf("%d%d",&a,&b); lca=getlca(a,b); printf("%d\n",lca); } return 0; }
倍增:
#include<bits/stdc++.h> using namespace std; const int mxn=500010; int n,m,S; struct node { int to,nxt; }e[mxn<<1]; int ecnt,head[mxn]; void add(int from,int to) { ++ecnt; e[ecnt].to=to; e[ecnt].nxt=head[from]; head[from]=ecnt; } int fa[mxn][20],dep[mxn]; void dfs(int u,int f) { fa[u][0]=f; for(int i=1;i<=19;i++) fa[u][i]=fa[fa[u][i-1]][i-1]; dep[u]=dep[f]+1; for(int i=head[u],v;i;i=e[i].nxt) { v=e[i].to; if(v==f) continue; dfs(v,u); } } int getlca(int x,int y) { if(dep[x]>dep[y]) swap(x,y); for(int i=19;i>=0;i--) if(dep[fa[y][i]]>=dep[x]) y=fa[y][i]; if(x==y) return x; for(int i=19;i>=0;i--) { if(fa[x][i]!=fa[y][i]) { x=fa[x][i]; y=fa[y][i]; } } return fa[x][0]; } int main() { scanf("%d%d%d",&n,&m,&S); for(int i=1,x,y;i<n;i++) { scanf("%d%d",&x,&y); add(x,y); add(y,x); } dfs(S,0); for(int i=1,x,y,lca;i<=m;i++) { scanf("%d%d",&x,&y); lca=getlca(x,y); printf("%d\n",lca); } return 0; }
12.堆:
#include<bits/stdc++.h> #define pa pair<int,int> #define mk make_pair using namespace std; inline int read() { int ans=0; char last=' ',ch=getchar(); while(ch>'9'||ch<'0') last=ch,ch=getchar(); while(ch>='0'&&ch<='9') ans=(ans<<1)+(ans<<3)+ch-'0',ch=getchar(); if(last=='-') ans=-ans; return ans; } int n,siz; int heap[1000080]; void insert(int x) { heap[++siz]=x; int nxt,now=siz; while(now>1) { nxt=now>>1; if(heap[nxt]<=heap[now]) break; swap(heap[now],heap[nxt]); now=nxt; } } void Delete() { heap[1]=heap[siz--]; int now=1,nxt; while((now<<1)<=siz) { nxt=now<<1; if(nxt<siz&&heap[nxt+1]<heap[nxt]) nxt++; if(heap[now]<=heap[nxt]) break; swap(heap[now],heap[nxt]); now=nxt; } } int main() { n=read(); for(int i=1,opt,x;i<=n;i++) { opt=read(); if(opt==1) { x=read(); insert(x); } if(opt==2) printf("%d\n",heap[1]); if(opt==3) Delete(); } return 0; }
13.逆元:
定義:
若\(ax\equiv 1(\mod b)\),且a與b互質,那麼咱們就能定義: x爲a的逆元,記爲\(a^{-1}\),因此咱們也能夠稱 x 爲 a 在 \(\mod b\) 意義下的倒數,
1.擴展歐幾里得算法:
由逆元定義可知,求a在mod b意義下的逆元,就是求ax+by=1的解,所以咱們可使用擴歐算法:
int exgcd(int a,int b,int &x,int &y) { if(b==0){x=1;y=0;return a;} int g=exgcd(b,a%b,x,y); int t=x; x=y; y=t-a/b*x; }
2.利用費馬小定理或者歐拉定理
費馬小定理:
若是 a,p 互質,那麼 \(a^{p-1} ≡ 1 \ \ (mod \ p)\)
由此能夠推出,\(a^{-1}=a^{p-2}\)
那麼咱們就能夠用快速冪來完成求逆元的任務;
歐拉定理:
若是a,p互質,那麼\(a^{\phi(p)} ≡ 1 \;(mod\; p)\),當 p 爲質數時,\(\phi(p)=p-1\)。
(只順手寫個快速冪行吧?)
ll quick_pow(int x,int k) { ll ans=1; while(k){ if(k&1) ans=(ans*x)%mod; x=(x*x)%mod; } return ans; }
3.線性遞推(用於求解一段數的逆元
\[ 令p=ki+r;k=\left\lfloor\dfrac{p}{i}\right\rfloor,r=p\%i \ \ \ (i<p,k<p,r<i)\\ 則有:ki+r\equiv 0(mod \ p)①\\ ①式左右同乘i^{-1}\times r^{-1}得:\\ kr^{-1}+i^{-1}\equiv 0(mod \ p)\\ 移項得:i^{-1} \equiv -k*r^{-1} (mod\ p) \\ 帶入 k=\left\lfloor\dfrac{p}{i}\right\rfloor,r=p\%i\\ i^{-1}\equiv -\left\lfloor\dfrac{p}{i}\right\rfloor*(p\mod i)^{-1}(mod\ p)\\ 因爲(p\mod i)<i\\ 所以在求出i^{-1}以前,咱們已經求出(p\mod i)^{-1}\\ 用inv數組記錄逆元 則:inv[i]=-\left\lfloor\dfrac{p}{i}\right\rfloor*inv[p\mod i] \mod p\\ 爲了保證逆元>0,因此要在右邊+p,即:inv[i]=-\left\lfloor\dfrac{p}{i}\right\rfloor*inv[p\mod i]+p \mod p\\ inv[1]=1;inv[0]=tan\frac{π}{2}設爲0 \]
#include<bits/stdc++.h> #define ll long long using namespace std; int n,p; ll inv[3000010]; int main() { scanf("%d%d",&n,&p); inv[1]=1; puts("1"); for(int i=2;i<=n;i++) { inv[i]=((-(p/i)*inv[p%i]+p)%p+p)%p; printf("%lld\n",inv[i]); } return 0; }
14.矩陣加速:(模板
$$
a[1]=a[2]=a[3]=1;\
a[x]=a[x-1]+a[x-3] (a>3)
\[ 轉移矩陣: \]
\begin{vmatrix}a_3\a_{2}\a_{1}\end{vmatrix}\times \begin{vmatrix}1&0&1\1&0&0\0&1&0\end{vmatrix}^{n-3}=\begin{vmatrix}a_{n}\a_{n-1}\a_{n-2}\end{vmatrix}
$$
15.高精度:
#include<bits/stdc++.h> using namespace std; char A[10090],B[10090]; int a[10090],b[10090],c[10090]; void sum() { scanf("%s",A); int lena=strlen(A); for(int i=0;i<lena;i++) a[lena-i]=A[i]-'0'; scanf("%s",B); int lenb=strlen(B); for(int i=0;i<lenb;i++) b[lenb-i]=B[i]-'0'; int len=max(lena,lenb); for(int i=1;i<=len;i++) { c[i]=a[i]+b[i]; } for(int i=1;i<=len;i++) { c[i+1]+=(c[i]/10); c[i]%=10; } if(c[len+1]!=0) len++; for(int i=len;i>=1;i--) printf("%d",c[i]); } void jian(){ int bj=1; scanf("%s",A); scanf("%s",B); int lena=strlen(A); int lenb=strlen(B); if(lena<lenb) { bj=-1; swap(A,B); swap(lena,lenb); } if(lena==lenb&&strcmp(A,B)<0) { bj=-1; swap(A,B); swap(lena,lenb); } for(int i=0;i<lena;i++) a[lena-i]=A[i]-'0'; for(int i=0;i<lenb;i++) b[lenb-i]=B[i]-'0'; int len=max(lena,lenb); for(int i=1;i<=len;i++) c[i]=a[i]-b[i]; for(int i=1;i<=len;i++) { if(c[i]<0) { c[i]+=10; c[i+1]--; } } if(bj==-1) printf("-"); while(c[len]==0&&len>1) len--; for(int i=len;i>=1;i--) printf("%d",c[i]); } void Mul() { scanf("%s",A); int lena=strlen(A); for(int i=0;i<lena;i++) a[lena-i]=A[i]-'0'; scanf("%s",B); int lenb=strlen(B); for(int i=0;i<lenb;i++) b[lenb-i]=B[i]-'0'; for(int i=1;i<=lena;i++) for(int j=1;j<=lenb;j++) c[i+j-1]+=a[i]*b[j]; for(int i=1;i<=lena+lenb-1;i++) { c[i+1]+=(c[i]/10); c[i]%=10; } int len=lena+lenb-1; while(c[len+1]>0) { c[len+2]+=(c[len+1]/10); c[len+1]%=10; len++; } for(int i=len;i>=1;i--) printf("%d",c[i]); } int main() { scanf("%s",A); int lena=strlen(A); for(int i=0;i<lena;i++) a[lena-i]=A[i]-'0'; int B; scanf("%d",&B); for(int i=lena;i>=1;i--) { c[i]=a[i]/B; a[i-1]+=(a[i]%B)*10; } while(c[lena]==0&&lena>0) lena--; for(int i=lena;i>=1;i--) printf("%d",c[i]); return 0; }
16.ST表:
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; const int inf=2147483647; inline ll read() { char ch=getchar(); ll x=0; bool f=0; while(ch<'0'||ch>'9') { if(ch=='-') f=1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=(x<<3)+(x<<1)+(ch^48); ch=getchar(); } return f?-x:x; } int n,m,a[1000009],st[1000009][23]; int lg[100009]; int qry(int l,int r) { int qwq=log((double)(r-l+1))/log(2.0); return max(st[l][qwq],st[r-(1<<qwq)+1][qwq]); } int main() { n=read();m=read(); for(int i=1;i<=n;i++) { a[i]=read(); st[i][0]=a[i]; } for(int i=1;(1<<i)<=n;i++) { for(int j=1;j<=n;j++) { st[j][i]=max(st[j][i-1],st[j+(1<<(i-1))][i-1]); } } while(m--) { int l=read(),r=read(); printf("%d\n",qry(l,r)); } }
17.高斯消元:
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> using namespace std; typedef long long ll; typedef long double ld; typedef pair<int,int> pr; const double pi=acos(-1); #define rep(i,a,n) for(int i=a;i<=n;i++) #define per(i,n,a) for(int i=n;i>=a;i--) #define Rep(i,u) for(int i=head[u];i;i=Next[i]) #define clr(a) memset(a,0,sizeof a) #define pb push_back #define mp make_pair #define fi first #define sc second ld eps=1e-9; ll pp=1000000007; ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;} ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;} ll read(){ ll ans=0; char last=' ',ch=getchar(); while(ch<'0' || ch>'9')last=ch,ch=getchar(); while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar(); if(last=='-')ans=-ans; return ans; } //head(lh的代碼頭) int n,m; double a[100][100]; bool check(int k){ if(fabs(a[k][n+1])<eps)return 1;// 若是小於0,返回1 for(int i=1;i<=n;i++) if(fabs(a[k][i])>eps)return 1;//第k行的每一個數都大於0 return 0; } int main(){ n=read();m=read();//m*n的矩陣, // a_i,1 a_i,2 ... a_i,n a_i,n+1 for(int i=1;i<=m;i++) for(int j=1;j<=n+1;j++)a[i][j]=read();//輸入矩陣元素(由於除了這個m*n的矩陣,還要有一行答案qwq) (看洛谷題吧qwq) for(int j=1;j<=m;j++){ for(int k=1;k<=n+1;k++)cout<<a[j][k]<<" "; puts(""); }//先把矩陣輸出遼一遍 int flag=0; for(int i=1;i<=n;i++){ int t=i; while(a[t][i]==0 && t<=n)t+=1; if(t==n+1){ flag=1; continue; }//if判斷是否有一行全爲0,若是全爲0 那麼咱們就少了至少1個方程,那麼這個方程顯然無惟一解 for(int j=1;j<=n+1;j++)swap(a[i][j],a[t][j]);//交換第i行和第t行的值,目的在於交換第i行和第t行後可使a[1][1]!=0 double kk=a[i][i];//找到對角線qwq for(int j=1;j<=n+1;j++)a[i][j]/=kk;//把這一行的每一項都除以對角線,使得對角線爲1 for(int j=1;j<=m;j++) //這裏真的要詳細地講一講咯 if(i!=j){//首先i!=j這樣就再也不消對角線上的數了 double kk=a[j][i];//定義kk爲第j行第i列的數 for(int k=1;k<=n+1;k++)//把每一項消成0qwq(先把第一列除了對角線全消爲0而後第二第三……) // 關於處理對角線這裏以i=1,j=3作例子:當k=3時,a[3][3]-=a[3][1]*a[1][3]而這個時候a[3][1]已經爲0,故對對角線無影響 a[j][k]-=kk*a[i][k]; } puts("------------");//畫一個槓槓來分割每一次消元結果 for(int j=1;j<=m;j++){ for(int k=1;k<=n+1;k++)cout<<a[j][k]<<" ";//輸出每次消元結果 puts("");//輸出空格 } } if(flag){//判斷無解和多解的狀況(上面已經提到了) 已經懵bi求救qwq for(int i=1;i<=m;i++) if(!check(i)){//利用check判斷是無解仍是多解 printf("No solution\n"); return 0; } //每一個答案行若是有一個等於0的數就多解?? printf("So many solutions\n"); } } ------------------------- #include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> using namespace std; long long read(){ long long ans=0; char last=' ',ch=getchar(); while(ch<'0' || ch>'9')last=ch,ch=getchar(); while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar(); if(last=='-')ans=-ans; return ans; } int n,m; double a[100][100]; int main(){ n=read(); for(int i=1;i<=n;i++) for(int j=1;j<=n+1;j++)a[i][j]=read(); int flag=0; for(int i=1;i<=n;i++){ int t=i; while(a[t][i]==0 && t<=n)t+=1; if(t==n+1){ flag=1; continue; } for(int j=1;j<=n+1;j++)swap(a[i][j],a[t][j]); double kk=a[i][i]; for(int j=1;j<=n+1;j++)a[i][j]/=kk; for(int j=1;j<=n;j++) if(i!=j){ double kk=a[j][i]; for(int k=1;k<=n+1;k++) a[j][k]-=kk*a[i][k]; } } if(flag)printf("No Solution\n"); else {for(int i=1;i<=n;i++) printf("%.2lf\n",a[i][n+1]);} return 0; } //和上面代碼差很少的,只不過這個輸出的是第n+1行,也就是每個未知數的解(由於都消成1了qwq)
18.矩陣求逆:
#include<cstdio> #include<iostream> using namespace std; typedef long long LL; const int N=405; int mod; int n,m; LL f[N][N<<1];//與下文相照應,這裏N<<1指N/2,爲了構造單位矩陣而乘的2 LL r,ret; LL ksm(LL u,LL v){ ret=1; while(v){ if(v&1)ret=ret*u%mod; u=u*u%mod;v>>=1; } return ret; } int main(){ scanf("%d%d",&n,&mod); m=n*2; //乘2是爲了後面創建一個單位矩陣 for(int i=1;i<=n;++i){ for(int j=1;j<=n;j++) scanf("%lld",&f[i][j]);//輸入n*n的矩陣 f[i][n+i]=1; //在 f後面又搞了一個單位矩陣qwq } for(int i=1;i<=n;++i){ //高斯消元的板子 for(int j=i;j<=n;j++) if(f[j][i]){ for(int k=1;k<=m;k++) swap(f[i][k],f[j][k]); break; } if(!f[i][i]){ puts("No Solution"); return 0; } //判斷是否有解(對角線爲0) r=ksm(f[i][i],mod-2); for(int j=i;j<=m;++j) f[i][j]=f[i][j]*r%mod; for(int j=1;j<=n;++j) if(j!=i){ r=f[j][i]; for(int k=i;k<=m;++k) f[j][k]=(f[j][k]-r*f[i][k]%mod+mod)%mod; } } for(int i=1;i<=n;++i,puts("")) for(int j=n+1;j<=m;++j) printf("%lld ",f[i][j]); return 0; }