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 ...
随机推荐
- HTML5 Performance
简介 performance是html5的新特性之一,通过它,页面的开发者们可以非常精确的统计到自己页面的表现情况,从而有针对性的进行优化,提升用户体验. 下面是小姐姐对performance相关AP ...
- 深入HTTP协议
一.HTTP定义 超文本传输协议(HTTP)是一种通信协议,它允许将超文本标记语言(HTML)文档从Web服务器传送到客户端的浏览器. HTTP是一个属于应用层的面向对象协议,由于其简捷.快速的方式, ...
- TextView显示html样式的文字
项目需求: TextView显示一段文字,格式为:白雪公主(姓名,字数不确定)向您发来了2(消息个数,不确定)条消息 这段文字中名字和数字的长度是不确定的,还要求名字和数字各自有各自的颜色. 一开始我 ...
- 使用js实现复选框的全选、取消功能
id为all的想设置全选的那个框的id,name为checkname[]的是每个小复选框: 第一种: <script> function checkAll() { var all=docu ...
- Python学习笔记.md
Python学习笔记 1.变量类型 x=5 int x="ss" string x='a' string x=True bool #查看变量类型 type(x) 2.字符串常用操作 ...
- TCP/IP 协议标准简单描述
TCP/IP 协议标准简单描述 说明 分为三部分:中文名称.缩写.说明. 应用层 DNS 域名服务 (DNS) 功能: 将域名转化为IP地址 BOOTP 引导程序协议 (BOOTP) 功能: 允许无盘 ...
- Java学习day21
今天学习了弹窗,除了此前学的按键以外,弹窗也是程序中广泛使用到的一个方面 做了一个简单的弹窗 除了按键以外,有时候我们需要在界面上显示更多的内容,甚至是图片等,这个时候就需要使用到标签 通过标签和Ic ...
- Vue使用PostCSS 插件和如何使用sass及常用语法
为什么要使用PostCss 转换 px 单位的插件有很多,知名的有 postcss-px-to-viewport 和 postcss-pxtorem,前者是将 px 转成 vw,后者是将 px 转成 ...
- BurpSuite下提示embedded browser initialisation failed(嵌入式浏览器初始化失败)的解决方法
BurpSuite可谓是渗透测试过程经常使用的神器之一,但使用中经常会碰到奇奇怪怪的问题,比如有时抓http包,发送到Repeater(中继器,也叫重发器)模块后,在右边Render模块下,却无法看到 ...
- 使用Lua 脚本实现redis 分布式锁,报错:ERR Error running script (call to f_8ea1e266485534d17ddba5af05c1b61273c30467): @user_script:10: @user_script: 10: Lua redis() command arguments must be strings or integers .
在使用SpringBoot开发时,使用RedisTemplate执行 redisTemplate.execute(lockScript, redisList); 发现报错: ERR Error run ...