zoukankan      html  css  js  c++  java
  • P5027 【Barracuda】

    适合初学高斯消元

    题目还是很好理解的,每次给定几个三角形和重量,就可以建立(n+1)个方程,转化为高斯消元模板

    想一想高斯消元的模板长什么样子,一个(n*(n+1))的矩阵,但是按照上面的思路来建立的话,会搞出来一个((n+1)*(n+1))的矩阵,那么就会遇到一些坑

    思路就是假设每一行都是错误的情况

    1. 并不是每一个编号的系数为(1),最开始我这里想了很久,可以抓多次同个三角形

    2. 如何假设是(x)行出错,对于高斯消元时的处理,并不能直接(continue)当前行,还是应该存储一个模板矩阵

    然后就继续说如何判断题目中的条件

    1. 最重的三角形只有一个,我们只需要在回代过后,对(maxx)的个数记录一下即可

    2. 不存在重量不确定的三角形,说明该方程在转化为“上三角形”之后,出现了(0=0)这类恒等式,表示无数组解,当然无解也是这样

    3. 三角形重量是正整数,我们用(duoble)来存储答案,如果(int)强制转换后的值比(duoble)类型小,说明不是正整数

    4. 对于不是合法方案,其实就是相当于当(i)错误时,我们能求出来一组解,当(j)错误时,我们也能求出来一组解,说明(illegal)

    #include<bits/stdc++.h>
    using namespace std;
    const double eps=1e-6;
    double a[150][150];
    double b[150][150];
    int n,m,x;
    int maxx,pre;
    int gauss() {
    	int c,r;
    	for(c=1,r=1; c<=n; c++) {
    		int t=r;
    		for(int i=r; i<=n; i++) {
    			if(fabs(a[t][c])<fabs(a[i][c])) t=i;
    		}
    		if(fabs(a[t][c])<eps) return 0;
    		for(int i=c; i<=n+1; i++) swap(a[r][i],a[t][i]);
    		for(int i=n+1; i>=c; i--) a[r][i]/=a[r][c];
    		for(int i=r+1; i<=n; i++) {
    			if(fabs(a[i][c])>eps) {
    				for(int j=n+1; j>=c; j--) a[i][j]-=a[r][j]*a[i][c];
    			}
    		}
    		r++;
    	} //高斯消元模板 
    	for(int i=n; i>=1; i--) {
    		for(int j=i+1; j<=n; j++) {
    			a[i][n+1]-=a[j][n+1]*a[i][j];
    		}
    		if(a[i][n+1]<eps||((int)a[i][n+1])<a[i][n+1]) return 0; //无解或是重量为小数的情况 
    	} //回代 
    	int sum;
    	maxx=-1;
    	for(int i=1; i<=n; i++) {
    		if((int)a[i][n+1]>maxx) maxx=a[i][n+1],sum=i;
    	} //记录最值 
    	int num=0;
    	for(int i=1; i<=n; i++) {
    		if((int)a[i][n+1]==maxx) num++; //最值数量 
    	}
    	if(num>1) return 0;
    	return sum;
    }
    int tot;
    int main() {
    	scanf("%d",&n);
    	for(int i=1; i<=n+1; i++) {
    		scanf("%d",&m);
    		for(int j=1; j<=m; j++) {
    			scanf("%d",&x);
    			b[i][x]++;
    		}
    		scanf("%d",&x);
    		b[i][n+1]=x*1.0;
    	} //存储初始的(n+1)*(n+1)的矩阵 
    	for(int i=1; i<=n+1; i++) {
    		int cnt=0;
    		for(int h=1; h<=n+1; h++) {
    			if(h==i) continue;
    			cnt++;
    			for(int k=1; k<=n+1; k++) {
    				a[cnt][k]=b[h][k];
    			}
    		} //存储一个n*(n+1)的矩阵 
    		int p=gauss();
    		if(p==0) continue; //无解或者无数组解 
    		else tot++,pre=p; //tot表示有几组解,pre是答案 
    	}
    	if(tot>1||tot==0) puts("illegal"); //全部无解或者出现多组解 
    	else cout<<pre;  
    	return 0;
    }
    
  • 相关阅读:
    虚拟机中对centOS7.4配置静态ip
    mybatis使用中出现的错误!
    http中get和post方法区别
    java中堆和栈的区别
    struts2工作流程
    springmvc工作流程
    JDBC访问数据库流程
    并行程序设计模式-Master-Worker模式-Guarded Suspension模式-不变模式-生产者-消费者模式的理解
    Future模式个人理解
    分布式系统一致性问题和Raft一致性算法
  • 原文地址:https://www.cnblogs.com/Poetic-Rain/p/13672548.html
Copyright © 2011-2022 走看看