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 ...
随机推荐
- JavaScript 工作原理之七-Web Workers 分类及 5 个使用场景
Web Workers 分类及 5 个使用场景 原文请查阅这里,略有删减,本文采用知识共享署名 4.0 国际许可协议共享,BY Troland. 这是 JavaScript 工作原理的第七章. 本系列 ...
- 【uniapp 开发】字符串工具类 StringUtil
替换字符串中的所有 "***" 子串 var str='Is this all there is'; var subStr=new RegExp('is','ig');//创建正则 ...
- 小程序wx.previewImage查看图片再次点击返回时重新加载页面问题
wx.previewImage预览图片这个过程到底发生了什么? 首先我们点击图片预览,附上查看图片代码: <image class="headImg" data-src=&q ...
- 小程序中webview内嵌h5页面
小程序内嵌h5页面跳转小程序指定页面, 需要引用 JSSDK: <script src="https://res.wx.qq.com/open/js/jweixin-1.3.2 ...
- Exchange日志
Exchange日志是exchange的重要组成部分,也是管理exchang的重要指标.exchange日志产生的速度很快,而且会占用大量磁盘空间.如何管理日志成为exchange管理员的重要管理任务 ...
- ThinkCMF[仿骑呗共享单车官网]
学习Thinkcmf内容管理系统(Thinkphp3.2.3框架)时候,用来练手的,简单的模仿骑呗官网首页,并对后台管理做了点小修改. 安装: 下载地址:https://pan.baidu.com/s ...
- Ncrystal Skill设计
在使用allegro时一般都会听说过skill,使用合适的Skill会使事情事半功倍.但是现阶段所能看到的个人白嫖的Skill都有一些通病.所以我才开发符合自己操作习惯的Skill. 当前我们所能找的 ...
- OllyDbg---寄存器
寄存器 寄存器的概念和作用 寄存器是CPU内部的高速存储单元,访问速度比常规内存快很多. 处理器在执行程序时,需要一个助手,当执行一条指令时,比如将两个内存单元中存放的内容相加,处理器需要先把其中一个 ...
- npm 报错This is probably not a problem with npm. There is likely additional logging output above.
报错This is probably not a problem with npm. There is likely additional logging output above. 安装了一个插件后 ...
- 2021.08.16 P1078 文化之旅(最短路)
2021.08.16 P1078 文化之旅(最短路) 题意: n个地,k个信仰,每个地都有自己的信仰,信仰之间会相互排斥,同信仰之间也会相互排斥,有m条路,问从s到t的最短距离是多少? 有一位使者要游 ...