2015年第六届蓝桥杯Java程序设计本科B组决赛个人题解汇总:
https://blog.csdn.net/daixinliangwyx/article/details/90051040
第五题
标题:表格计算
交题测试地址:https://www.dotcpp.com/oj/problem1832.html
某次无聊中, atm 发现了一个很老的程序。这个程序的功能类似于 Excel ,它对一个表格进行操作。
不妨设表格有 n 行,每行有 m 个格子。
每个格子的内容可以是一个正整数,也可以是一个公式。
公式包括三种:
1. SUM(x1,y1:x2,y2) 表示求左上角是第 x1 行第 y1 个格子,右下角是第 x2 行第 y2 个格子这个矩形内所有格子的值的和。
2. AVG(x1,y1:x2,y2) 表示求左上角是第 x1 行第 y1 个格子,右下角是第 x2 行第 y2 个格子这个矩形内所有格子的值的平均数。
3. STD(x1,y1:x2,y2) 表示求左上角是第 x1 行第 y1 个格子,右下角是第 x2 行第 y2 个格子这个矩形内所有格子的值的标准差。
标准差即为方差的平方根。
方差就是:每个数据与平均值的差的平方的平均值,用来衡量单个数据离开平均数的程度。
公式都不会出现嵌套。
如果这个格子内是一个数,则这个格子的值等于这个数,否则这个格子的值等于格子公式求值结果。
输入这个表格后,程序会输出每个格子的值。atm 觉得这个程序很好玩,他也想实现一下这个程序。
「输入格式」
第一行两个数 n, m 。
接下来 n 行输入一个表格。每行 m 个由空格隔开的字符串,分别表示对应格子的内容。
输入保证不会出现循环依赖的情况,即不会出现两个格子 a 和 b 使得 a 的值依赖 b 的值且 b 的值依赖 a 的值。
「输出格式」
输出一个表格,共 n 行,每行 m 个保留两位小数的实数。
数据保证不会有格子的值超过 1e6 。
「样例输入」
3 2
1 SUM(2,1:3,1)
2 AVG(1,1:1,2)
SUM(1,1:2,1) STD(1,1:2,2)
「样例输出」
1.00 5.00
2.00 3.00
3.00 1.48
「数据范围」
对于 30% 的数据,满足: n, m <= 5
对于 100% 的数据,满足: n, m <= 50
资源约定:
峰值内存消耗(含虚拟机) < 512M
CPU消耗 < 2000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。
解法:就是个递归来模拟,先将初始矩阵存在二维String数组里,然后遍历矩阵,如果遇到是公式就进行计算处理,考虑到公式里面计算到某行某列时可能又是一个公式,所以应该采用递归的方式来求公式的值,并在求公式值完成后立即将其值存到ans数组里,以免后续重复计算公式,遍历完整个矩阵输出ans数组就可以了。
代码:
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.DecimalFormat;
import java.util.*;
public class Main4 {
public static InputReader in = new InputReader(new BufferedInputStream(System.in));
public static PrintWriter out = new PrintWriter(System.out);
public static int n, m, num, sx, sy, ex, ey;
public static int[][] vis = new int[55][55];
public static String[][] map = new String[55][55];
public static double[][] ans = new double[55][55];
public static void main(String[] args) {
n = in.nextInt();
m = in.nextInt();
num = 0;
DecimalFormat df = new DecimalFormat("0.00");
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
map[i][j] = in.next();
if (Character.isDigit(map[i][j].charAt(0))) {
ans[i][j] = Double.parseDouble(map[i][j]);
vis[i][j] = 1;
num++;
}
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (ans[i][j] == 0) {
ans[i][j] = getValue(i, j);
}
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
out.print(df.format(ans[i][j]) + " ");
out.flush();
}
out.println();
out.flush();
}
out.close();
}
static double getValue(int x, int y) {
if (ans[x][y] != 0) return ans[x][y];
else {
sx = Integer.parseInt(((map[x][y].split(":")[0]).split("\\(")[1]).split(",")[0]);//
sy = Integer.parseInt(((map[x][y].split(":")[0]).split("\\(")[1]).split(",")[1]);
ex = Integer.parseInt(((map[x][y].split(":")[1]).split("\\)")[0]).split(",")[0]);
ey = Integer.parseInt(((map[x][y].split(":")[1]).split("\\)")[0]).split(",")[1]);
if (map[x][y].charAt(2) == 'M') {//求和函数
double sum = 0;
for (int i = sx; i <= ex; i++) {
for (int j = sy; j <= ey; j++) {
sum += getValue(i, j);
}
}
ans[x][y] = sum;
return sum;
} else if (map[x][y].charAt(2) == 'G') {
double sum = 0;
int k = 0;
for (int i = sx; i <= ex; i++) {
for (int j = sy; j <= ey; j++) {
sum += getValue(i, j);
k++;
}
}
ans[x][y] = sum / k;
return sum / k;
} else {
double sum = 0;
int k = 0;
for (int i = sx; i <= ex; i++) {
for (int j = sy; j <= ey; j++) {
sum += getValue(i, j);
k++;
}
}
double avg = sum / k;
sum = 0;
for (int i = sx; i <= ex; i++) {
for (int j = sy; j <= ey; j++) {
sum += (getValue(i, j) - avg) * (getValue(i, j) - avg);
}
}
ans[x][y] = Math.sqrt(sum/k);
return Math.sqrt(sum/k);
}
}
}
static class InputReader {
public BufferedReader reader;
public StringTokenizer tokenizer;
public InputReader(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 32768);
tokenizer = null;
}
public String next() {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
public String nextLine() {
String str = null;
try {
str = reader.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
public int nextInt() {
return Integer.parseInt(next());
}
public long nextLong() {
return Long.parseLong(next());
}
public Double nextDouble() {
return Double.parseDouble(next());
}
public BigInteger nextBigInteger() {
return new BigInteger(next());
}
public BigDecimal nextBigDecimal() {
return new BigDecimal(next());
}
}
}
评测结果: