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();}
    
  • 相关阅读:
    Go语言十六进制转十进制
    Go语言中底层数组和切片的关系以及数组扩容规则
    Golang超时机制--2秒内某个函数没被调用就认为超时
    约瑟夫环问题(猴子选大王)
    冒泡排序优化
    斐波那契数列
    Linux下使用acme.sh (Let's Encrypt) 配置https 免费证书
    git 本地分支指定对应的远程分支
    Git分支开发 -- 利用git pull命令将远程指定仓库的分支拉取到本地
    phpStorm 之 本地开发,Linux上跑项目(连接远端服务器开发)
  • 原文地址:https://www.cnblogs.com/nanfeng-blog/p/15028808.html
Copyright © 2011-2022 走看看