goose消元
ps.改了标题
魔板
思路:按序消除变量,用当前行(i)【行i消\(x_i\)元素】,消后面的每一行的i元素
最后按逆序回代值
注意若有i~n行i元素系数都为0说明没有唯一解(其余x的解跟i元素有关),没事,跳过i元素不跳过i行继续算,最后判断系数全为0的情况下值是否为0代码:
#include<bits/stdc++.h>
using namespace std;
const int N=105;
double a[N][N],eps=1e-8;
int main() {
int n;
scanf("%d",&n);
for(int i=0;i<n;i++) for(int j=0;j<=n;j++)scanf("%lf",&a[i][j]);
//校园
for(int i=0;i<n;i++) { //j:当前的变量,i:第几行
int r=i;
for(int k=i+1;k<n;k++)
if(fabs(a[k][i])>fabs(a[r][i])) r=k;
if(fabs(a[r][i])<eps) {printf("No Solution");return 0;}
if(r!=i) {
for(int j=0;j<=n;j++) swap(a[r][j],a[i][j]);
}
for(int k=i+1;k<n;k++) {
double s=a[k][i]/a[i][i];
for(int l=0;l<=n;l++) {
a[k][l]-=a[i][l]*s;
}
}
}
//回代
for(int i=n-1;i>=0;i--) {
a[i][n]=a[i][n]/a[i][i];
for(int j=0;j<i;j++) {
a[j][n]-=a[j][i]*a[i][n];
}
}
for(int i=0;i<n;i++) printf("%.2lf\n",a[i][n]);
return 0;
}
补充几道习题。
SETI
- 思路:一道版题,但因为我上课听的不够认真而误解。
同余方程下成立直接最小正整数成立即可Qwq
那就很水了,不贴代码
球形空间产生器
- 思路:我不知道为什么可以相邻的来搞在一起就会对。总之假如这样,用数学推导就很容易了。
中央暖气
- 思路:文字游戏,然后引进了一类新的xor类型的高斯消元,其实还比浮点数好写些.
- 代码(xor)
//我是傻逼 我是傻逼 我是傻逼
#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
const int N=305;
int n;
bool a[N][N];
bool Guass() {
for(int i=1;i<=n;i++) {
int r=i;
while(!a[r][i]&&r<n) r++;
if(!a[r][i]) {return false;}
if(r!=i) {
for(int j=1;j<=n+1;j++) swap(a[r][j],a[i][j]);
}
for(int j=i+1;j<=n;j++) {
if(a[j][i]) {
for(int k=1;k<=n+1;k++) a[j][k]^=a[i][k];
}
}
}
for(int i=n;i;i--) {
for(int j=1;j<i;j++) {
a[j][n+1]^=a[j][i]*a[i][n+1];
}
}
for(int i=1;i<=n;i++) {
if(a[i][n+1]) printf("%d ",i);
}
return true;
}
int main() {
scanf("%d",&n);
for(int i=1;i<=n;i++) {
int x;
while(1) {
scanf("%d",&x);
if(x==-1) break;
a[x][i]=1;
}
}
for(int i=1;i<=n;i++) a[i][n+1]=1;
if(!Guass())printf("No solution");
return 0;
}
ps.之所以sb因为没初始化调了30min
开关问题
- 思路:这道考察对自由元的理解:
1.出现自由元只会lead to two sides无解或者多解
2.若多解,无论自由元取值什么值,非自由元依旧有解。(即自由元与非自由元无明显联系)
然后,这道题就答案:2^自由元的个数
手机游戏
思路:这个也写了好久,就很烦。(震惊!原因竟然是for循环没有枚举到0,而是枚举到了1)
思路就是二进制枚举自由元选取状态,一个一个带回取消元。代码:
#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
const int N=2005;
char s[N][N];
bool is_free[N],tmp[N],a[N][N];
int lst,b[N][N],n,Free[N],num,dir[7][2]={{0,0},{1,0},{-1,0},{0,-1},{0,1}};
bool Goose() {
int i,j;
for(i=0,j=0;i<n&&j<n;) {
int r=i;
while(!a[r][j]&&r<=n) r++;
if(r>n) {is_free[j]=1;Free[num++]=j++;continue;}
if(r!=i) for(int k=0;k<=n;k++)swap(a[i][k],a[r][k]);
for(int k=i+1;k<n;k++) {
if(a[k][j]) {
for(int l=0;l<=n;l++) a[k][l]^=a[i][l];
}
}
i++,j++;
}
for(int k=i;k<n;k++) if(a[k][n]){return false;}
lst=i;
return true;
}
int Freedom() {
int ans=1e9;
for(int s=0;s<(1<<num);s++) {
for(int i=0;i<n;i++) tmp[i]=a[i][n];
int res=0;
for(int i=0;i<num;i++) {
if((1<<i)&s) {
res++;
for(int k=0;k<n;k++) {
tmp[k]^=a[k][Free[i]];
}
}
}
int i=lst-1;
for(int j=n-1;j>=0;j--) {
if(is_free[j])continue;
res+=tmp[i];
for(int k=0;k<i;k++) {
tmp[k]^=tmp[i]*a[k][j];
}
i--;
}
ans=min(ans,res);
}
return ans;
}
int main() {
int q;
scanf("%d",&q);
for(int i=0;i<q;i++) scanf("%s",s[i]);
for(int i=0;i<q;i++)for(int j=0;j<q;j++)b[i][j]=n++;
for(int i=0;i<q;i++)for(int j=0;j<q;j++)a[b[i][j]][n]=(s[i][j]=='w');
for(int i=0;i<q;i++)for(int j=0;j<q;j++) {
for(int d=0;d<5;d++) {
int x=i+dir[d][0],y=j+dir[d][1];
if(x<0||y<0||x>=q||y>=q)continue;
a[b[x][y]][b[i][j]]=1;
}
}
if(!Goose()) printf("inf");
else {
int ans=Freedom();
printf("%d",ans);
}
return 0;
}
[USACO3.2.4】Feed Ratios饲料调配
思路:告诉我们两件事
1.若多了一个变量别急着看题解(我很后悔),直接暴力枚举这个变量即可。
2.有毒瘤出题人卡高斯消元弄出了x.9999..这种数据,然后fabs((int)x.9999-x.9999)=1然后就挂了
解决方法就是一切浮点数+eps(越小越好)代码:
//这题的浮点数误差剧坑
//(int)4.9999999...=4
#include<bits/stdc++.h>
using namespace std;
int b[5][5];
double a[5][5],eps=1e-14;
bool Guass() {
for(int i=1;i<=3;i++) {
int r=i;
for(int k=i+1;k<=3;k++)
if(fabs(a[k][i])>fabs(a[r][i])) r=k;
if(fabs(a[r][i])<eps) {return false;}
if(r!=i) {
for(int j=1;j<=4;j++) swap(a[r][j],a[i][j]);
}
for(int k=i+1;k<=3;k++) {
double s=a[k][i]/a[i][i];
for(int l=1;l<=4;l++) {
a[k][l]-=a[i][l]*s;
}
}
}
for(int i=3;i>=1;i--) {
a[i][4]=a[i][4]/a[i][i];
for(int j=1;j<i;j++) {
a[j][4]-=a[j][i]*a[i][4];
}
}
return true;
}
int main() {
int x,y,z,X,Y,Z;
scanf("%d%d%d",&x,&y,&z);
for(int i=1;i<=3;i++) {
for(int j=1;j<=3;j++) {
scanf("%d",&b[i][j]);
}
}
for(int k=1;k<=100;k++) {
for(int j=1;j<=3;j++) {
for(int i=1;i<=3;i++) {
a[j][i]=b[i][j];
}
}
X=x*k,Y=y*k,Z=z*k;
a[1][4]=X,a[2][4]=Y,a[3][4]=Z;
if(Guass()) {
bool flag=true;
for(int i=1;i<=3;i++) {
if(a[i][4]-(int)a[i][4]>eps&&(int)(a[i][4]+eps)==(int)a[i][4]||a[i][4]+eps<0) {flag=false;break;}
}
if(flag) {
for(int i=1;i<=3;i++) printf("%d ",(int)(a[i][4]+eps));
printf("%d",k);
return 0;
}
}
}
printf("NONE");
return 0;
}
外星千足虫
- 思路:在每次找到非零行时取max,注意用bitset优化一个O(W)
注意bitset是一个二进制,只能整体运算,但可以取单体的值。 - 代码:
#include<bits/stdc++.h>
using namespace std;
const int N=2e3+5;
bitset<N> a[N];
char s[N];
int k,n,m,b[N];
void Guass() {
for(int i=0;i<n;i++) {
int r=i;
while(r<m&&!a[r][i]) r++;
if(r==m) {printf("Cannot Determine");exit(0);}
k=max(k,r);
if(i!=r) swap(a[i],a[r]),swap(b[i],b[r]);
for(int j=i+1;j<m;j++) {
if(a[j][i]) {
a[j]^=a[i],b[j]^=b[i];
}
}
}
for(int i=n-1;i>=0;i--) {
for(int j=0;j<i;j++) {
b[j]^=b[i]*a[j][i];
}
}
}
int main() {
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++) {
int x;
scanf("%s%d",s,&x);
for(int j=0;j<n;j++) a[i][j]=s[j]-'0';
b[i]=x;
}
Guass();
printf("%d\n",k+1);
for(int i=0;i<n;i++) {
if(b[i]) printf("?y7M#\n");
else printf("Earth\n");
}
return 0;
}
【CQOI2014】和谐矩阵【毒瘤版】
一切的源头就是NKOJ男鞋的spj,然后就进阶成了一道思维题(字典)
- 思路:或许其它人都是用的暴力+贪心,但是我是直接贪心(没有任何暴力,跑得飞快)
首先,我们容易想到倒着消元,这样越前面的数只要不是一定确定,被定为自由元的优先级就更高
所以回代的顺序就是顺着的。
其次,自由元的性质是该自由元后面的行都为0,而我们是倒着消元的,因此自由元不影响前面的取值(字典序),所以我们直接将所有自由元取0。
你会发现矩阵全零了!!!
最后,我们贪心:将最后一个自由元赋为1,然后顺势回代,跟原高斯消元的代码相近,然后就AC啦。
贪心就用“其次……”这个性质非常的好证明。 - 代码:
1485 B
源代码
#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
const int N=2005;
int a[N][N];
bool is_free[N];
int h,l,fst,b[N][N],n,cnt=0,dir[7][2]={{0,0},{1,0},{-1,0},{0,1},{0,-1}};
void Print() {
for(int i=0;i<n;i++) {
if(i&&i%l==0) printf("\n");
if(i==fst) printf("1 ");
else if(is_free[i]) printf("0 ");
else printf("%d ",a[i][n]);
}
}
void Guass() {
int i,j,r;
for(i=n-1,j=n-1;i>=0&&j>=0;) {
r=i;
while(r>=0&&!a[r][j]) {r--;}
if(r<0) {if(!fst)fst=j;is_free[j]=1,--j;continue;}
if(i!=r) swap(a[i],a[r]);
for(int k=i-1;k>=0;k--) {
if(a[k][j]) {
for(int l=0;l<=n;l++) a[k][l]^=a[i][l];
}
}
--i,--j;
}
// Print();
// Print2();
i++; j++;
while(i<n&&j<n) {
// printf("%d %d\n",i,j);
if(fst==j) {
for(int k=i;k<n;k++) if(a[k][j])a[k][n]^=1;
j++; continue;
}
else if(is_free[j]) {j++;continue;}
else if(a[i][n]) {
for(int k=i+1;k<n;k++) {
a[k][n]^=a[i][n]*a[k][j];
}
}
i++,j++;
// Print();
// Print2();
}
}
int main() {
scanf("%d%d",&h,&l);
for(int i=1;i<=h;i++) for(int j=1;j<=l;j++) b[i][j]=cnt++;
for(int i=1;i<=h;i++) for(int j=1;j<=l;j++) {
for(int t=0;t<5;t++) {
int x=i+dir[t][0],y=j+dir[t][1];
if(x<1||y<1||x>h||y>l) continue;
a[b[i][j]][b[x][y]]=1;
}
}
n=h*l;
Guass();
Print();
return 0;
}
goose消元的更多相关文章
- 【BZOJ-3143】游走 高斯消元 + 概率期望
3143: [Hnoi2013]游走 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2264 Solved: 987[Submit][Status] ...
- 【BZOJ-3270】博物馆 高斯消元 + 概率期望
3270: 博物馆 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 292 Solved: 158[Submit][Status][Discuss] ...
- *POJ 1222 高斯消元
EXTENDED LIGHTS OUT Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 9612 Accepted: 62 ...
- [bzoj1013][JSOI2008][球形空间产生器sphere] (高斯消元)
Description 有一个球形空间产生器能够在n维空间中产生一个坚硬的球体.现在,你被困在了这个n维球体中,你只知道球 面上n+1个点的坐标,你需要以最快的速度确定这个n维球体的球心坐标,以便于摧 ...
- hihoCoder 1196 高斯消元·二
Description 一个黑白网格,点一次会改变这个以及与其连通的其他方格的颜色,求最少点击次数使得所有全部变成黑色. Sol 高斯消元解异或方程组. 先建立一个方程组. \(x_i\) 表示这个点 ...
- POJ1288 Sly Number(高斯消元 dfs枚举)
由于解集只为{0, 1, 2}故消元后需dfs枚举求解 #include<cstdio> #include<iostream> #include<cstdlib> ...
- BZOJ 2844 albus就是要第一个出场 ——高斯消元 线性基
[题目分析] 高斯消元求线性基. 题目本身不难,但是两种维护线性基的方法引起了我的思考. void gauss(){ k=n; F(i,1,n){ F(j,i+1,n) if (a[j]>a[i ...
- SPOJ HIGH Highways ——Matrix-Tree定理 高斯消元
[题目分析] Matrix-Tree定理+高斯消元 求矩阵行列式的值,就可以得到生成树的个数. 至于证明,可以去看Vflea King(炸树狂魔)的博客 [代码] #include <cmath ...
- UVALive 7138 The Matrix Revolutions(Matrix-Tree + 高斯消元)(2014 Asia Shanghai Regional Contest)
题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=6 ...
随机推荐
- python-验证6174猜想
[题目描述]1955年,卡普耶卡(D.R.Kaprekar)对4位数字进行了研究,发现一个规律:对任意各位数字不相同的4位数,使用各位数字能组成的最大数减去能组成的最小数,对得到的差重复这个操作,最终 ...
- idea怎么创建python项目
前言 python是一种功能强大和适用面很广的开发语言,在大数据应用和机器学习日益流行的年代,python凭借其简洁.易用和可扩展性获得很多用户的支持,近年来使用率高速增长.python环境下,集成了 ...
- ES7中前端异步特性:async、await。
在最新的ES7(ES2017)中提出的前端异步特性:async.await. 什么是async.await? async顾名思义是"异步"的意思,async用于声明一个函数是异步的 ...
- BootstrapBlazor实战-Tree树形控件使用(1)
实战BootstrapBlazor树型控件Tree的使用, 以及整合Freesql orm快速制作数据库后台维护页面 demo演示的是Sqlite驱动,FreeSql支持多种数据库,MySql/Sql ...
- Power App用到的一些函数
1.Filter([表名],查询条件&&查询条件),会返回一张表: 2.Search([表名], "值", "字段名"),会返回一张表: 3.L ...
- 重定向管道流读取TXT文本第一次读取为""空字符串、type xxx.txt | go run . 报错、BOM头、[239,186,191] 字节数组
重定向管道流读取TXT文本第一次读取为""空字符串.type xxx.txt | go run . 报错.BOM头.[239 186 191] 字节数组
- node.js - http、模块化、npm
今天是node学习的第二天,其实越往后面学越感觉有点熟悉的味道了,光针对于node来说哈,为什么呢,因为我之前学过一点云计算的东西,当时感觉没什么用搞了下服务器客户端这些,没想到这里还能用一用,至少看 ...
- “浪潮杯”第九届山东省ACM大学生程序设计竞赛 F: Four-tuples容斥定理
题目 F : Four-tuples 输入 1 1 1 2 2 3 3 4 4 输出 1 题意 给l1, r1, l2, r2, l3, r3, l4, r4 , 八个数据, 要求输出在区间[l ...
- 详解MySQL索引
原文链接详解MySQL索引 索引介绍 索引是帮助MySQL高效获取数据的数据结构.在数据之外,数据库系统还维护着一个用来查找数据的数据结构,这些数据结构指向着特定的数据,可以实现高级的查找算法. 本文 ...
- [洛谷] P2241 统计方形(数据加强版)
点击查看代码 #include<bits/stdc++.h> using namespace std; long long n, m, total, sum1, sum2; int mai ...