解题思路:
用Grid结构保存每个格子的值,它的成员有格子串(串长小于20)、格子“坐标”(左上角和右下角的行列号)以及格内实数的值。若表格有n行m列,对于30%的数据,满足:n,m <= 5,对于100%的数据,满足:n,m <= 50,可定义格子数组,100行100列应该足够了。不管格内是公式还是实数,先当成格子串输入,分析该串,因为输入数据保证不会有格子的值超过1e6,那么实数串的长度不大于7,而公式串的长度应该在12到16左右,由此区分两类串;若为公式串,用分隔符将公式名和行列号隔开,将行列号转换成整型数,若为实数串转换成浮点数,并保存为Grid类型的数组元素;接下来为了求得指定行列号的格子值,需要用“格子函数”,若格内是数,很简单,直接返回格子值等于这个数,若格内是公式,就要调用“求公式的函数”,求公式的过程中,又要调用“格子函数”,两类函数相互嵌套,直到所有公式对应的格子值返回实数结果。
注意事项:
在“格子函数”中,用公式名中间字符'U'、'V'、'T'区分“求和”、“求平均数”、“求标准差”。
参考代码:#include
#include
#include
#include
#include
typedef struct SGrid{
char s[20];
int p[4];
double r;
}Grid;
Grid grid[100][100];
int n,m;
double sum(int,int,int,int);
double avg(int,int,int,int);
double std(int,int,int,int);
double y(int,int);
int main(){
int i,j,c;
char *t;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
scanf("%s",grid[i][j].s);
if(strlen(grid[i][j].s)>7){ //格内公式
c=0;
t=strtok(grid[i][j].s,"(,:)"); //分隔符将公式隔开
while(t){
t=strtok(NULL,"(,:)");
if(t) grid[i][j].p[c++]=atoi(t); //左上角右下角行列号
}
}else grid[i][j].r=atof(grid[i][j].s); //格内浮点数
}
}
for(i=1;i<=n;i++){
printf("%.2lf",y(i,1));
for(j=2;j<=m;j++){
printf(" %.2lf",y(i,j)); //求得格子值
}
printf("\n");
}
return 0;
}
double y(int i,int j){
if(isdigit(grid[i][j].s[0])){ //这一格是数字
return grid[i][j].r;
}else if(grid[i][j].s[1]=='U'){ //指定格子行列号,求和
return sum(grid[i][j].p[0],grid[i][j].p[1],grid[i][j].p[2],grid[i][j].p[3]);
}else if(grid[i][j].s[1]=='V'){ //指定格子行列号,求平均数
return avg(grid[i][j].p[0],grid[i][j].p[1],grid[i][j].p[2],grid[i][j].p[3]);
}else if(grid[i][j].s[1]=='T'){ //指定格子行列号,求标准差
return std(grid[i][j].p[0],grid[i][j].p[1],grid[i][j].p[2],grid[i][j].p[3]);
}
}
double avg(int x1,int y1,int x2,int y2){ //平均数
double sum=0;
int cnt=0;
for(int i=x1;i<=x2;i++){
for(int j=y1;j<=y2;j++){
sum+=y(i,j); //加格子值
cnt++;
}
}
return sum/(cnt*1.0);
}
double sum(int x1,int y1,int x2,int y2){ //和
double sum=0;
for(int i=x1;i<=x2;i++)
for(int j=y1;j<=y2;j++)
sum+=y(i,j); //加格子值
return sum;
}
double std(int x1,int y1,int x2,int y2){ //标准差
double temp,sum=0;
int cnt=0;
for(int i=x1;i<=x2;i++){
for(int j=y1;j<=y2;j++){
sum+=y(i,j); //加格子值
cnt++;
}
}
double temp2=sum/cnt*(1.0); //平均数
sum=0;
for(int i=x1;i<=x2;i++){
for(int j=y1;j<=y2;j++){
temp=y(i,j); //取得格子值
temp=fabs(temp-temp2);
temp*=temp; //与平均值差的平方
sum+=temp;
}
}
return sqrt(sum/(cnt*1.0));
}