wa了整天,变换着姿势终于找到错了。。
1.模拟过程,字符串的处理,字符串里包含数字,()括号,字母,数字注意是负数,会坑你爹的
一开始注意到了负数,以为处理了,但是没处理好,没有在读取整个负数后才乘以-1,所以错了
2.高斯消元过程,出现undefined是因为出现了 a=a 这样的式子,也就是有自由变量
注意一个变量a的undefined可能导致另一变量b的undefined,只要b的式子包含a,这样令我wa不止,
我注意到了,以为处理了,,可是又没处理好。。
可以如下,正常消元过程后,回代的时候判断代入的是不是undefined,和对应的check
void gauss() { for(int i=0;i<n;++i) { int pivot=i; for(int k=i+1;k<n;++k) if(fabs(a[k][i])>fabs(a[pivot][i])) pivot=k; if(pivot!=i) { for(int j=0;j<=n;++j) swap(a[pivot][j],a[i][j]); } if(fabs(a[i][i])<eps) continue; for(int k=i+1;k<n;++k) for(int j=n;j>=i;--j) a[k][j]-=a[k][i]/a[i][i]*a[i][j]; } for(int i=n-1;i>=0;--i) // 包含有undefined的字母的式子也会变成undefined { for(int k=n-1;k>i;--k) if(fabs(a[k][k])>eps) { a[i][n]-=a[i][k]*a[k][n]; } else if(fabs(a[i][k])>eps) { a[i][i]=0.0; break; } a[i][n]/=a[i][i]; } } inline bool check(int x) { return fabs(a[x][x])>eps; }
其他entry有不是0的,或者,a[i][i]的位置是0 ,说明undefined
void gauss() { for(int row=0,col=0;row<n && col<n;++row,++col) { int pivot=row; for(int k=row+1;k<n;++k) if(a[k][col]>a[pivot][col]) pivot=k; if(pivot!=row) { for(int j=0;j<=n;++j) swap(a[pivot][j],a[row][j]); } if(fabs(a[row][col])<eps) { continue; } for(int k=0;k<n;++k) if(k!=row) { double mul=a[k][col]/a[row][col]; for(int j=0;j<=n;++j) a[k][j]-= mul * a[row][j]; } } } bool check_exist(int x) { for(int j=0;j<n;++j) if(j!=x) { if(fabs(a[x][j])>eps) return false; } return (fabs(a[x][x])>eps); }
最终代码:C++能过,G++wa。不解。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <map> #include <set> #include <algorithm> #include <ctime> #include <vector> #include <string> using namespace std; #define eps 1e-9 double a[30][30]; char s[10000]; int n; // - num ( ) char void cal(int pos,int st,int ed,int now) // s[st]=='(' { bool prenum=false; int p=0,block=0; // p is the number of object for(int i=st;i<=ed;++i) { if(block==1 && s[i]>='0' && s[i]<='9') { if(!prenum && block==1) p++; prenum=true; } else { prenum=false; if(s[i]=='(') { if(block==1) p++; block++; } else if(s[i]==')') block--; else if(block==1 && s[i]>='a' && s[i]<='z') p++; } } prenum=false;block=0; now*=p; int num,nest_st,nest_ed,mark; for(int i=st;i<=ed;++i) { if(block==1 && s[i]>='0' && s[i]<='9') { if(!prenum) { prenum=true; num=s[i]-'0'; mark=1; if(s[i-1]=='-') mark=-1; } else num=num*10+s[i]-'0'; } else { if(prenum) { prenum=false; num*=mark; a[pos][n]+=num*1.0/now; } if(s[i]=='(') { if(block==1) nest_st=i; block++; } else if(s[i]==')') { block--; if(block==1) { nest_ed=i; cal(pos,nest_st,nest_ed,now); } } else if(block==1 && s[i]>='a' && s[i]<='z') { a[pos][s[i]-'a']-=1.0/now; } } } } void gauss() { for(int i=0;i<n;++i) { int pivot=i; for(int k=i+1;k<n;++k) if(fabs(a[k][i])>fabs(a[pivot][i])) pivot=k; if(pivot!=i) { for(int j=0;j<=n;++j) swap(a[pivot][j],a[i][j]); } if(fabs(a[i][i])<eps) continue; for(int k=i+1;k<n;++k) for(int j=n;j>=i;--j) a[k][j]-=a[k][i]/a[i][i]*a[i][j]; } for(int i=n-1;i>=0;--i) // 包含有undefined的字母的式子也会变成undefined { for(int k=n-1;k>i;--k) if(fabs(a[k][k])>eps) { a[i][n]-=a[i][k]*a[k][n]; } else if(fabs(a[i][k])>eps) { a[i][i]=0.0; break; } a[i][n]/=a[i][i]; } } inline bool check(int x) { return fabs(a[x][x])>eps; } int main () { int ncase=1; while(scanf("%d",&n)!=EOF) { if(n==0 ) break; memset(a,0,sizeof(a)); char ch; int st,ed,block; for(int i=0;i<n;++i) { scanf("%c",&ch); gets(s); a[i][i]=1.0; block=0; for(int j=0;;++j) if(s[j]=='(') { if(block==0) st=j; block++; } else if(s[j]==')') { block--; if(block==0) { ed=j; break; } } cal(i,st,ed,1); } gauss(); printf("Game %d\n",ncase++); for(int i=0;i<n;++i) { if(check(i)) printf("Expected score for %c = %.3lf\n",'a'+i,a[i][n]); else printf("Expected score for %c undefined\n",'a'+i); } printf("\n"); } return 0; }