POJ 1487 表达式解析+高斯消元法

//Result:wizmann	1487	Accepted	784K	0MS	G++	3034B	

#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <iostream>

#include <algorithm>

#include <vector>

#include <string>

#include <cmath>



using namespace std;



#define print(x) cout<<x<<endl

#define input(x) cin>>x

#define MAT 32

#define SIZE 1024

#define pb push_back



const double eps=1e-8;



inline bool zero(double x){return fabs(x)<eps;}



struct node

{

	int type;

	int val;

	

	node(){}

	node(int i_type,int i_val)

	{

		type=i_type;

		val=i_val;

	}

};



vector<int> g[SIZE];

double mat[MAT][MAT];

node array[SIZE];

int n;

int ind;

char *p;



void build(int now)

{

	int t,m;

	while(*p)

	{

		while(*p==' ' && *p) p++;

		if(!*p) break;

		if( (*p>='0' && *p<='9') || *p=='-')

		{

			ind++;

			sscanf(p,"%d%n",&t,&m);

			p+=m;

			array[ind]=node(0,t);

			g[now].pb(ind);

		}

		else if(*p=='(')

		{

			ind++;

			array[ind]=node(-1,0);

			p++;

			g[now].pb(ind);

			build(ind);

		}

		else if(*p==')')

		{

			p++;

			return;

		}

		else

		{

			ind++;

			array[ind]=node(1,*p-'a');

			p++;

			g[now].pb(ind);

		}

	}

}

			

void toMatrix(int now,double tp,int var)

{

	double p;

	if(g[now].size()) p=tp/g[now].size();

	

	//写入Matrix的基本原理:

	//例如a = (2 , b)

	//a的E(a)期望等于 1/2 * 2 + 1/2 * E(b)

	//所以,对于Mat[ord(a)]来说,即为:

	//		1*E(A) -1/2*E(B) = 1/2*2

	for(int i=0;i<(int)g[now].size();i++)

	{

		int x=g[now][i];

		if(array[x].type==-1)

		{

			toMatrix(x,p,var);

		}

		else

		{

			if(array[x].type==0)

			{

				mat[var][n]+=array[x].val*p;

			}

			else

			{

				mat[var][array[x].val]-=p;

			}

		}

	}

}



void init()

{

	ind=0;

	memset(array,0,sizeof(array));

	for(int i=0;i<SIZE;i++) g[i].clear();

}



void gauss_line(int a,int b,int col)

{

	double mul_a=mat[a][col];

	double mul_b=mat[b][col];

	for(int i=0;i<=n;i++)

	{

		mat[b][i]=mat[b][i]-mat[a][i]*mul_b/mul_a;

	}

}



void gauss()

{

	for(int row=0,col=0;row<n && col<n;row++,col++)

	{

		int ptr=-1;

		for(int i=row;i<n;i++)

		{

			if(!zero(mat[i][col]))

			{

				ptr=i;

				break;

			}

		}

		if(ptr==-1) continue;

		else

		{

			for(int i=0;i<=n;i++)

			{

				swap(mat[row][i],mat[ptr][i]);

			}

			for(int i=0;i<n;i++) if(i!=row)

			{

				gauss_line(row,i,col);

			}

		}

	}

}



double getans(int x)

{

	return mat[x][n]/mat[x][x];

}



bool check_exist(int x)

{

	for(int i=0;i<n;i++) if(i!=x)

	{

		if(!zero(mat[x][i])) return false;

	}

	return !zero(mat[x][x]);

}



int main()

{

	int cas=1;

	char cmd[SIZE];

	while(input(n) && n)

	{

		memset(mat,0,sizeof(mat));

		printf("Game %d\n",cas++);

		for(int i=0;i<n;i++)

		{

			init();

			do

			{

				gets(cmd);

			}while(*cmd=='\0');

			p=cmd;

			while(*p!='(') p++;

			//p++;

			build(0);

			toMatrix(0,1.,i);

			mat[i][i]+=1.0;

		}

		gauss();

		for(int i=0;i<n;i++)

		{

			if(check_exist(i)) printf("Expected score for %c = %.3f\n",i+'a',getans(i));

			else printf("Expected score for %c undefined\n",i+'a');

		}

		puts("");

	}

	return 0;

}

		

  

你可能感兴趣的:(poj)