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
其他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;
}