zoukankan      html  css  js  c++  java
  • NOIP 模拟 $18; m 炼金术士的疑惑$

    题解 (by;zjvarphi)

    高斯消元

    根据高中化学知识,求解方程的就是一直方程凑出来的,焓值也一样

    那么对于要求的方程和一直方程,我们做一次高斯消元,以每个物质为未知数,因为它保证有解,所以消完元后,求解方程的各项系数一定为 (0) 代表我们凑出这个方程了,最后答案就是求出来的值的相反数

    读入时用 (hash)(map) 都行,输出时要特判 (0.0)

    Code
    #include<bits/stdc++.h>
    #define ri register signed
    #define p(i) ++i
    using namespace std;
    namespace IO{
        char buf[1<<21],*p1=buf,*p2=buf;
        #define gc() p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++
        template<typename T>inline void read(T &x) {
            ri f=1;x=0;register char ch=getchar();
            while(ch<'0'||ch>'9') {if (ch=='-') f=0;ch=getchar();}
            while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
            x=f?x:-x;
        }
    }
    using IO::read;
    namespace nanfeng{
        #define FI FILE *IN
        #define FO FILE *OUT
        template<typename T>inline T cmax(T x,T y) {return x>y?x:y;}
        template<typename T>inline T cmin(T x,T y) {return x>y?y:x;}
        typedef double db;
        static const int N=2e3+7;
        static const db eps=1e-8;
        map<string,db> mp[N],cl;
        int n,cnt;
        db H[N],mat[N][N],tmp;
        string ts,al[N];
        inline db Gauss() {
            for (ri i(1);i<=n&&i<=cnt;p(i)) {
                int k=i;
                for (ri j(i+1);j<=n;p(j)) 
                    if (fabs(mat[k][i])<fabs(mat[j][i])) k=j;
                if (k!=i) swap(mat[k],mat[i]);
                for (ri j(1);j<=n+1;p(j)) {
                    if (i==j) continue;
                    db tp=mat[j][i]/mat[i][i];
                    for (ri l(1);l<=cnt+1;p(l)) 
                        mat[j][l]-=mat[i][l]*tp;
                }
            }
            return -mat[n+1][cnt+1];
        }//高斯约旦
        inline int main() {
            // FI=freopen("nanfeng.in","r",stdin);
            // FO=freopen("nanfeng.out","w",stdout);
            read(n);
            for (ri i(1);i<=n+1;p(i)) {
                while(1) {
                    scanf("%lf",&tmp);
                    cin >> ts;
                    if (ts[0]=='=') break;
                    if (cl.find(ts)==cl.end()) {al[p(cnt)]=ts;cl[ts]=1.0;} 
                    mp[i][ts]=tmp;
                    cin >> ts;
                    if (ts[0]=='=') break;
                }
                while(1) {
                    scanf("%lf",&tmp);
                    cin >> ts;
                    if (ts[0]=='H'&&ts[1]=='=') break;
                    if (cl.find(ts)==cl.end()) {al[p(cnt)]=ts;cl[ts]=1.0;} 
                    mp[i][ts]=-tmp;
                    cin >> ts;
                    if (ts[0]=='H'&&ts[1]=='=') break;
                }
                if (i<=n) scanf("%lf",&H[i]);
            }
            for (ri i(1);i<=n+1;p(i)) {
                for (ri j(1);j<=cnt;p(j)) {
                    if (mp[i].find(al[j])!=mp[i].end()) 
                        mat[i][j]=mp[i][al[j]];
                }
                if (i<=n) mat[i][cnt+1]=H[i];
            }
            db ans=Gauss();
            printf("%.1lf",fabs(ans)>eps?ans:0);
            return 0;
        }  
    }
    int main() {return nanfeng::main();}
    
  • 相关阅读:
    html5学习笔记
    J-Link eclipse Plug-ins install
    SEGGER J-Link install
    如何使用Redis实现分布式锁?
    在Redis里,如何从海量key中查询出某一个固定前缀所有的key?
    (必问)Redis有哪些常用数据类型?
    (必问)Http和Https的区别有哪些?
    Https的传输流程是什么?
    Cookie和Session有什么区别?
    HTTP的状态码有哪些?
  • 原文地址:https://www.cnblogs.com/nanfeng-blog/p/15028808.html
Copyright © 2011-2022 走看看