poj 1487 Single-Player Games(高斯消元+字符串处理)
2016-11-28 21:38
501 查看
题意:
给你几棵树,每棵树的叶子节点都有一个值,这个值可能是直接给出,也可能是其它树的期望值,问每棵树走到叶子节点获得的值的期望是多少。
每棵树的编号是从a到a+n-1.
思路:
被这道题,卡了好几天,快卡哭了QAQ。
首先麻烦的是字符串的处理,用递归是一种比较好的办法,先记录下同一个括号里所存在的元素个数,再往下递归就好。
然后建立方程。记a树的期望为Ea,把有确定值的叶子节点的期望求出来加和为va,以及求出走到存放其它树(str)的期望的叶子节点的概率记为a[str-'a'],
则可列出方程: Ea=Ea*a['a'-'a']+Eb*a['b'-'a']+Ec*a['c'-'a']……+va;
移项得:va=(1-Ea)*a['a'-'a']-Eb*a['b'-'a']-Ec*a['c'-'a']......(我的程序不这样移就会wa,不知道为什么)
然后每棵树都可以列出这样的一个方程,套用下高消消元浮点型解模板。
但是这个题还需要注意一个情况,当出现有自由变元的时候,并不是就有多解,对于一些只包含一个自由变元的方程组,是可以求解的,我们就要求出这些方程组中那个唯一的自由变元的解,而对于其它不能确定的变元,输出undefined即可。
这题真恶心!
代码:
给你几棵树,每棵树的叶子节点都有一个值,这个值可能是直接给出,也可能是其它树的期望值,问每棵树走到叶子节点获得的值的期望是多少。
每棵树的编号是从a到a+n-1.
思路:
被这道题,卡了好几天,快卡哭了QAQ。
首先麻烦的是字符串的处理,用递归是一种比较好的办法,先记录下同一个括号里所存在的元素个数,再往下递归就好。
然后建立方程。记a树的期望为Ea,把有确定值的叶子节点的期望求出来加和为va,以及求出走到存放其它树(str)的期望的叶子节点的概率记为a[str-'a'],
则可列出方程: Ea=Ea*a['a'-'a']+Eb*a['b'-'a']+Ec*a['c'-'a']……+va;
移项得:va=(1-Ea)*a['a'-'a']-Eb*a['b'-'a']-Ec*a['c'-'a']......(我的程序不这样移就会wa,不知道为什么)
然后每棵树都可以列出这样的一个方程,套用下高消消元浮点型解模板。
但是这个题还需要注意一个情况,当出现有自由变元的时候,并不是就有多解,对于一些只包含一个自由变元的方程组,是可以求解的,我们就要求出这些方程组中那个唯一的自由变元的解,而对于其它不能确定的变元,输出undefined即可。
这题真恶心!
代码:
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> using namespace std; const int maxn=1e2; const double eps=1e-8; int n; char str[maxn+5]; double a[maxn+5][maxn+5]; double b[maxn+5]; double kh[maxn+5]; bool v[maxn+5]; bool freex[maxn+5]; //记录是否为自由变元 struct eee { int s; double p; int valu; int zt; } que[maxn+5]; void gauss(int n) { int i, j, row, col, equ=n, var=n; for(row=0, col=0; row<equ && col<var; row++, col++) { int maxr=row; for(i=row; i<equ; i++) { if(fabs(a[i][col])>fabs(a[maxr][col])) { maxr=i; } } if(fabs(a[maxr][col])<eps) { row--; continue; } for(j=col; j<var+1; j++) { swap(a[maxr][j], a[row][j]); } for(i=row+1; i<equ; i++) { if(fabs(a[i][col])>eps) { double s=a[i][col]/a[row][col]; for(j=col; j<var+1; j++) { a[i][j]-=a[row][j]*s; } } } } if(row < n) { for(i=row-1; i>=0; i--) { int num=0, id; for(j=i; j<n; j++) //找出该方程中有几个自由变元 { if(freex[j] && fabs(a[i][j])>eps) { num++; id=j; //当出现只有一个自由变元时,就是id了 } } if(num>1)continue; // 有多个自由变元,该方程无解 double tmp=a[i] ; for(j=id+1; j<n; j++) { tmp-=a[i][j]*b[j]; } b[id]=tmp/a[i][id]; freex[id]=0; //已求出该变元的值,将其标记为非自由变元。 } for(i=0; i<n; i++) { printf("Expected score for %c ", i+'a'); if(!freex[i])printf("= %.3lf\n", b[i]); else printf("undefined\n"); } // printf("\n"); return; } for(i=equ-1; i>=0; i--) { double tmp=a[i][var]; for(j=i+1; j<var; j++) { tmp-=a[i][j]*b[j]; } // printf("%.3lf %d %.3lf\n", a[i][i], i, tmp); b[i]=tmp/a[i][i]; } for(i=0; i<n; i++) { printf("Expected score for %c = %.3lf\n", i+'a', b[i]); } } void find(int x, double p, int s, int d) { int i, j; int num=0;// kuohao number double enumber=0.0; // element number for(i=s+1; i<d; i++) { if(str[i]=='(') { num++; } else if(str[i]==')') { num--; if(num==0) { enumber+=1; } } else if(str[i]!=' ' && num==0) { while(str[i+1]>='0' && str[i+1]<='9')i++; enumber+=1; } } num=0; int st=0; for(i=s+1; i<d; i++) { if(str[i]=='(') { if(num==0) st=i; num++; } else if(str[i]==')') { num--; if(num==0) { find(x, p*1.0/enumber, st, i); } } else if(str[i]>='a' && str[i]<='z' && num==0) { a[x][str[i]-'a']-=p*1.0/enumber; } else if(str[i]=='-' && num==0) { int ans=0; i++; while(str[i]>='0' && str[i]<='9') { ans=ans*10+str[i]-'0'; i++; } ans=-ans; a[x] +=1.0*ans*p/enumber; } else if(str[i]<='9' && str[i]>='0' && num==0) { int ans=0; while(str[i]<='9' && str[i]>='0') { ans=ans*10+str[i]-'0'; i++; } // printf("%lf %.0lf\n", ans*p/enumber, ans); a[x] +=1.0*ans*p/enumber; } } return; } int main() { int isfirst=1; int e=1; while(~scanf("%d", &n)) { if(n==0)break; int i, j; memset(v, 0, sizeof(v)); memset(a, 0, sizeof(a)); memset(freex, true, sizeof(freex)); //先将所有变量默认为自由变元,之后会在求解过程中求出哪些变元不是自由变元。 getchar(); for(i=0; i<n; i++) { gets(str); // printf("%s\n", str); double var=0; double p=1.0; a[i][i]=1; int st=0, ed=0, len=strlen(str); for(j=0; str[j]; j++) { if(str[j]=='(') { st=j;break; } } for(j=len-1; j>=0; j--)if(str[j]==')'){ed=j;break;} find(i, p, st, ed); } if(isfirst)isfirst=0; else printf("\n"); printf("Game %d\n", e++); gauss(n); } return 0; }
相关文章推荐
- POJ 1487:Single-Player Games 浮点数高斯消元
- poj_1487 Single-Player Games(高斯消元+自由元)
- poj 1487 Single-Player Games 高斯消元
- POJ 1487:Single-Player Games 浮点数高斯消元
- 【POJ1487】——Single-Player Games(高斯消元)
- poj 1487 Single-Player Games
- POJ 1487 Single-Player Games
- 【POJ 1487】Single-Player Games(建方程高消)
- poj1487--Single-Player Games(高斯消元)+测试数据
- POJ 1487 Single-Player Games
- POJ 1487 高斯消元+模拟……坑爹题~好题
- poj 1200 Hash处理字符串(简单的rabin-karp)
- POJ-2803 英文阅读+字符串处理
- POJ 2065 SETI 高斯消元
- poj 2408 Anagram Groups 字符串处理题
- POJ 1016 Numbers That Count(字符串处理)
- POJ 1830 开关问题 高斯消元
- POJ 1830 开关问题 高斯消元
- POJ 1681 Painter's Problem 高斯消元+DFS枚举
- POJ 3193 Cow Phrasebook(简单字符串的处理)