题意还是很好理解的,比如对于第二个样例
2
a = (1 b)
b = (4 a)
我们可以得出 a = 0.5+0.5*b , b = 0.5*4+0.5*a,这样就可以建立方程组来解题。
预处理有点麻烦,我是对于每个区间递归处理的,代码有点搓,但还是比较好理解的。
前面由于精度问题没经验,被坑了好几次。。。还很水,希望快点强大起来!
第一次发题解~真有趣
#include <stdio.h> #include <string.h> #include <math.h> #include <algorithm> using namespace std; double a[33][222] , x[33]; char s[33][222]; int n ; bool freex[33] ; double eps = 1e-6; void debug() { int i,j; puts("debug"); for(i = 0;i < n ;i++) { for(j = 0;j < n+1;j++) printf("%.3lf ", a[i][j]); puts(""); } puts("end"); } void find(int i,double d,int st,int to) { //i表示当前处理的字母 d表示前面处理出的倍数 int j,k; int num = 0 ; double x = 0 ; // x 当前区间有多少元素 for(j = st;j <= to; j++) if(s[i][j] == '(') num++; else if(s[i][j] == ')') { num--; if(num == 0) x = x+1; } else if(s[i][j] != ' ' && num == 0) { while(s[i][j+1] >= '0' && s[i][j+1] <= '9') j++; x = x+1; } //printf("st = %d to = %d x = %.0lf\n" , st, to, x); num = 0; int pre ; for(j = st;j <= to; j++) if(s[i][j] == '(') { if(num == 0) pre = j; num++; } else if(s[i][j] == ')' ) { num--; if(num == 0) find(i , d/x , pre+1,j-1); } else if(s[i][j] != ' ' && num == 0) { if(s[i][j] == '-') // 负数的情况 { int xx = 0; j++; while(s[i][j] >= '0' && s[i][j] <= '9') xx = xx*10+s[i][j]-'0' , j++; a[i][n] += -1.0*xx*d/x; } else if(s[i][j] >= 'a' && s[i][j] <= 'z' ) //字母的情况 a[i][ s[i][j]-'a' ] += -1.0*d/x; else { int xx = 0; while(s[i][j] >= '0' && s[i][j] <= '9') xx = xx*10+s[i][j] - '0' , j++; a[i][n] += 1.0*xx*d/x; } } } void gauss() { int row = 0 , col = 0 ; int i , j ; for( ; row < n && col < n; row++ , col++) { int maxr = row; for(i = row+1;i < n ; i++) if(a[i][col] != 0) maxr = i; if(fabs(a[maxr][col])<eps) // 注意精度 { row --; continue; } if(maxr != row) for(i = col;i < n +1;i ++) swap(a[maxr][i] , a[row][i]); for(i = row+1;i < n ; i++) { if(a[i][col] == 0) continue; double d = a[i][col]/a[row][col]; for(j = col;j < n+1;j ++) a[i][j] = a[i][j] - a[row][j]*d; } } // debug(); // printf("row = %d\n", row) ; 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 ; if(num > 1) continue; x[id] = a[i][n]; for(j = id+1;j < n ;j ++) x[id] -= a[i][j]*x[j]; x[id] /= a[i][id]; freex[id] = 0; } for(i = 0;i < n; i++) if(freex[i]) printf("Expected score for %c undefined\n", 'a'+i); else printf("Expected score for %c = %.3lf\n" , i+'a' , x[i]); puts(""); return ; } for(i = n-1;i >= 0;i --) { x[i] = a[i][n]; for(j = i+1;j < n ;j ++) x[i] -= x[j]*a[i][j]; x[i] = x[i]/a[i][i]; } for(i = 0;i < n; i++) printf("Expected score for %c = %.3lf\n" , i+'a' , x[i]); puts(""); } void init() { memset(a, 0, sizeof(a)) ; memset(freex , true , sizeof(freex)) ; } int main() { int i,j , cas = 1;; while(scanf("%d", &n) != -1 && n) { getchar() ; init(); for(i = 0;i < n ; i++) gets(s[i]) ; int st,to ; for(i = 0;i < n ;i++) { a[i][i] = 1; int len = strlen(s[i]); for(j = 0;j < len ; j++) if(s[i][j] == '(') { st =j; break; } for(j = len-1;j >= 0; j--) if(s[i][j] == ')' ) { to = j; break; } find(i,1.0,st+1,to-1); } // debug(); printf("Game %d\n", cas++); gauss(); } return 0; }