很久没有写题解了,因为我发现之前写的题没有写题解的现在再让我读题就忘的差不多了,比如置换群,当初看了好久,现在忘的差不多了,也许题解靠后写的好处是可以巩固啊!最近没有多少时间刷题了,快要考试了,最后两周还要数据库课程设计,还要学html和javascrpt,而我对着是完全没有接触过的,老师说以前都是几个人一组做一个大作业的,今年特殊,一个人做一个,所以,我是考前复习加上数据库设计,稍带还要备考六级,各种忙,所以最近题单上的题都没写了,只是这几天杭电上有比赛就做了,还是只会做水题的水平,现在晚上回到宿舍没事了就是研究比赛的那几道题,有的连别人的代码就实在看不懂是什么意思,想不出算法啊!算了,不废话了,说这题吧!
题目大意:给你一颗树,树的节点的值是已给的值乘上到这个结点的概率,当然,数的节点有可能是一个变量,然后每个树表达的是一个变量,然后根据这些树得到算式然后求得变量的值。
解题思路:首先要将树转换成方程,然后高斯消元,我是将树转换成方程这一步想了好久也不知道是该怎么写,最后又看了代码,还分析了好久。。。然后高斯消元,wa了很久不知道为什么,无语了都。。。今天杭电的复赛又被。。。后天学长和钢牛参加长沙的省赛,预祝他们取得好成绩吧!下面是代码;
#include<iostream> #include<string> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<queue> #include<stack> #include<vector> #include<climits> using namespace std; #define rep(i,n) for(int i=0; i<(n); i++) #define repf(i,n,m) for(int i=(n); i<=(m); i++)//正循环的 #define repd(i,n,m) for(int i=(n); i>=(m); i--) //负循环的 #define max(a,b) (a)>(b)?(a):(b) #define min(a,b) (a)<(b)?(a):(b) #define ll __int64 #define arc(a) ((a)*(a)) #define inf 10000000 //最大值的 #define exp 0.0000001 //浮点型的 #define N 10005 //记录开的数组 double a[104][N]; int n; int test=0; struct node { int st,p; node() {}; node(int st,int p):st(st),p(p){}; }; vector<node>q[N]; void dfs(int i,int l,double r) { // printf("") rep(j,q[l].size()) { if(q[l][j].st==2) dfs(i,q[l][j].p,r/q[l].size()); if(q[l][j].st==1) a[i][q[l][j].p]-=r/q[l].size(); if(q[l][j].st==0) a[i][n+1]+=q[l][j].p*r/q[l].size(); } } void fun() { memset(a,0,sizeof(a)); char s[N]; int len; repf(i,1,n) { rep(j,N) q[j].clear(); gets(s); len=strlen(s); stack<int>r; int now=0,t=0,m=0; int sign=0; r.push(0); int l; a[i][i]=1; rep(j,len) if(s[j]=='(') {l=j+1; break;} repf(j,l,len-1) { if(isdigit(s[j])) { m=m*10+s[j]-'0';if(sign==0) sign=1;} else { if(sign!=0) {q[now].push_back(node(0,m*sign)); m=sign=0;} if(isalpha(s[j])) q[now].push_back(node(1,s[j]-'a'+1)); if(s[j]=='(') {r.push(now); q[now].push_back(node(2,++t)); now=t;} if(s[j]==')') { now=r.top();r.pop();} if(s[j]=='-') sign=-1; } } dfs(i,0,1); } } double fab(double x) { if(fabs(x-0)<exp) return true; return false; } void guess() { // repf(i,1,n) {repf(j,1,n+1) printf("%lf ",a[i][j]);printf("\n");} repf(i,1,n) { int k=n+1; repf(j,i,n) if(!fab(a[j][i])) {k=j; break;} if(k>n) continue; // printf("%d %d\n",i,k); repf(j,1,n+1) swap(a[i][j],a[k][j]); // repf(i,1,n) {repf(j,1,n+1) printf("%lf ",a[i][j]);printf("\n");} repf(j,1,n) { if(j!=i) { /* double x=a[i][i],y=a[j][i]; repf(k,i,n+1) a[j][k]=a[j][k]*x-a[i][k]*y;*/ double x=a[j][i]/a[i][i]; repf(k,i,n+1) a[j][k]-=a[i][k]*x; } } } // repf(i,1,n) {repf(j,1,n+1) printf("%lf ",a[i][j]);printf("\n");} repf(i,1,n) if(fab(a[i][i])) repf(j,1,n) if(!fab(a[j][i])) a[j][j]=0; printf("Game %d\n",++test); repf(i,1,n) if(fab(a[i][i])) printf("Expected score for %c undefined\n",i+'a'-1); else printf("Expected score for %c = %0.3lf\n",i+'a'-1,a[i][n+1]/a[i][i]); printf("\n"); } int main() { while(scanf("%d",&n)) { if(n==0) break; getchar(); fun(); guess(); } return 0; }