原题链接:蓝桥杯2015年第六届真题-表格计算
解题思路:
用Grid结构保存每个格子的值,它的成员有格子串(串长小于20)、格子“坐标”(左上角和右下角的行列号)以及格内实数的值。若表格有n行m列,对于30%的数据,满足:n,m <= 5,对于100%的数据,满足:n,m <= 50,可定义格子数组,100行100列应该足够了。不管格内是公式还是实数,先当成格子串输入,分析该串,因为输入数据保证不会有格子的值超过1e6,那么实数串的长度不大于7,而公式串的长度应该在12到16左右,由此区分两类串;若为公式串,用分隔符将公式名和行列号隔开,将行列号转换成整型数,若为实数串转换成浮点数,并保存为Grid类型的数组元素;接下来为了求得指定行列号的格子值,需要用“格子函数”,若格内是数,很简单,直接返回格子值等于这个数,若格内是公式,就要调用“求公式的函数”,求公式的过程中,又要调用“格子函数”,两类函数相互嵌套,直到所有公式对应的格子值返回实数结果。
注意事项:
在“格子函数”中,用公式名中间字符'U'、'V'、'T'区分“求和”、“求平均数”、“求标准差”。
参考代码:
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<ctype.h> #include<math.h> 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)); }
0.0分
5 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复