absi2011's Blog & Daily Life.

全新的开始       我要省选翻盘       I wanna AK in 高考\化学       自此,生无可恋
[破碎的状态] [-32] 100324 I
[破碎的状态] [-31] 100324 C

[破碎的状态] [-32] 100324 E(高斯消元)

absi2011 posted @ Jun 20, 2016 11:56:57 PM in 刷题记录 with tags 小高考 高斯消元 CF Gym , 367 阅读

题意:http://absi2011.is-programmer.com/posts/202693.html

做法:

首先先膜拜yjz

然后按照yjz偏导求一下..

高斯消元求出所有的解..枚举每个变量是0,1还是消元得的解

没了(要判定这个解是否在[0,1]之内)

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<math.h>
#include<string>
#include<time.h>
#include<bitset>
#include<vector>
#include<memory>
#include<utility>
#include<stdio.h>
#include<sstream>
#include<fstream>
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
char a[10005];
int tx[205];
char out_val[205];
double c[15][15];
double d[15];
int cnt=0;
double cst=0;
int type[15];
double max_ans;
double sol[15];
const double eps=1e-8;
void check_ans()
{
    static double a[15][15];
    static double b[15];
    memcpy(a,c,sizeof(a));
    memcpy(b,d,sizeof(b));
    int i;
    for (i=0;i<cnt;i++)
    {
        if (type[i]!=2)
        {
            int j;
            for (j=0;j<cnt;j++)
            {
                a[i][j]=0;
            }
            a[i][i]=1;
            b[i]=type[i];
        }
        else
        {
            a[i][i]*=2;
        }
    }
    for (i=0;i<cnt;i++)
    {
        int j;
        for (j=i;j<cnt;j++)
        {
            if ((a[j][i]>eps)||(a[j][i]<-eps))
            {
                break;
            }
        }
        if (j==cnt) return;
        int k;
        for (k=0;k<cnt;k++)
        {
            swap(a[i][k],a[j][k]);
        }
        swap(b[i],b[j]);
        for (j=i+1;j<cnt;j++)
        {
            double x=a[j][i]/a[i][i];
            for (k=i+1;k<cnt;k++)
            {
                a[j][k]-=x*a[i][k];
            }
            b[j]-=b[i]*x;
            a[j][i]=0;
        }
    }
    for (i=cnt-1;i>=0;i--)
    {
        b[i]/=a[i][i];
        int j;
        for (j=0;j<i;j++)
        {
            b[j]-=a[j][i]*b[i];
        }
        if ((b[i]>1+eps)||(b[i]<0-eps)) return;
    }
    double now_ans=0;
    for (i=0;i<cnt;i++)
    {
        int j;
        for (j=i;j<cnt;j++)
        {
            now_ans+=b[i]*b[j]*c[i][j];
        }
        now_ans-=b[i]*d[i];
    }
    now_ans+=cst;
    if (now_ans>max_ans)
    {
        max_ans=now_ans;
        memcpy(sol,b,sizeof(sol));
    }
}
void dfs(int x)
{
    if (x==cnt)
    {
        check_ans();
        return;
    }
    type[x]=0;
    dfs(x+1);
    type[x]=1;
    dfs(x+1);
    type[x]=2;
    dfs(x+1);
}
int main()
{
    freopen("formula1.in","r",stdin);
    freopen("formula1.out","w",stdout);
    scanf("%s",a);
    int i;
    memset(tx,-1,sizeof(tx));
    for (i=0;a[i]!='\0';i++)
    {
        if ((tx[a[i]]==-1)&&((a[i]>='a')&&(a[i]<='z')))
        {
            tx[a[i]]=cnt;
            out_val[cnt]=a[i];
            cnt++;
        }
    }
    if (tx['e']!=-1)
    {
        for (i='a';i<='z';i++)
        {
            if (tx[i]==-1)
            {
                tx[i]=tx['e'];
                int j;
                for (j=0;a[j]!='\0';j++)
                {
                    if (a[j]=='e') a[j]=i;
                }
                break;
            }
        }
    }
    i=0;
    for (;;)
    {
        double b=1;
        sscanf(a+i,"%lf",&b);
        if ((a[i]=='-')&&((a[i+1]>='a')&&(a[i+1]<='z')))
        {
            b=-1;
        }
        if ((a[i]=='-')||(a[i]=='+')) i++;
        for (;;)
        {
            if (((a[i]<'0')||(a[i]>'9'))&&(a[i]!='.')) break;
            i++;
        }
        if ((a[i]>='a')&&(a[i]<='z'))
        {
            int x=tx[a[i]];
            i++;
            if (a[i]=='^')
            {
                i++;
                i++;
                c[x][x]+=b;
            }
            else if ((a[i]>='a')&&(a[i]<='z'))
            {
                c[x][tx[a[i]]]+=b;
                c[tx[a[i]]][x]+=b;
                i++;
            }
            else
            {
                d[x]-=b;
            }
        }
        else
        {
            cst+=b;
        }
        if (a[i]=='\0') break;
    }
    max_ans=cst;
    dfs(0);
    printf("%.6lf\n",max_ans);
    for (i=0;i<cnt;i++)
    {
        printf("%c=%.6lf\n",out_val[i],sol[i]);
    }
    return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter