E卷-Excel单元格数值统计-200分
E卷-刷题笔记合集🔗
题目描述
Excel工作表中对选定区域的数值进行统计的功能非常实用。请实现一个类似的功能,对给定表格中选中区域的单元格进行求和统计。
单元格内容分为两种类型:
- 数字:非负整数,如 3、77
- 公式:以=开头,包含以下三种情况:
- 等于某单元格的值,如 =B12
- 两个单元格的加减运算,如 =C1-C2、C3+B2
- 单元格和数字的加减运算,如 =B1+1、100-B2
输入格式
第一行输入两个整数 和
,表示表格的行数和列数:
接下来 行,每行
个以空格分隔的字符串,表示表格的单元格内容。
最后一行输入一个字符串,表示选中区域,格式如 A1:C2。
输出格式
输出一个整数,表示选中区域各单元格中数字的累加总和。
- 结果范围:
约束说明
-
公式内容保证合法:
- 不存在 =C+1、=C1-C2+B3、=5、=3+5 等非法格式
- 不存在循环引用,如 A1=B1+C1、C1=A1+B2
- 不存在空格、括号
-
表格规则:
- 行号范围:1~20
- 列号范围:A~Z
- 单元格B3对应values[2][1]
- 单元格数值范围:[0,100]
-
选中区域规则:
- 冒号左侧为左上角
- 冒号右侧为右下角
- 合法格式:B2:C10、B2:B5、B2:Y2、B2:B2
- 不存在:C2:B2、C2:A1 等非法格式
样例输入1
1 3
1 =A1+C1 3
A1:C1
样例输出1
8
样例解释1
如图所示:
样例输入2
5 3
10 12 =C5
15 5 6
7 8 =3+C2
6 =B2-A1 =C2
7 5 3
B2:C4
样例输出2
29
题解
这道题的关键点在于:
-
Excel坐标转换
- 列号: A->0, B->1, C->2 (ASCII码减65)
- 行号: 数字减1
-
公式解析
- 提取操作数和运算符
- 递归计算引用的单元格值
- 更新计算结果
-
区域求和
- 确定选中区域范围
- 遍历计算每个单元格
- 累加求和
实现思路:
-
定义辅助函数:
- getPos: 解析Excel坐标
- getCellVal: 计算单元格值
- operate: 执行加减运算
-
主要步骤:
- 读取表格数据
- 解析选中区域
- 遍历求和计算
时间复杂度:
参考代码
def solve():
# 读取输入
rows, cols = map(int, input().split())
table = [input().split() for _ in range(rows)]
start, end = input().split(":")
# 记录已计算的单元格值
cache = {}
# 解析Excel坐标为矩阵索引
def get_pos(cell):
col = ord(cell[0]) - ord('A')
row = int(cell[1:]) - 1
return row, col
# 计算单元格的值
def get_cell_val(cell):
if cell[0] == '=':
expr = cell[1:]
if '+' in expr:
a, b = expr.split('+')
return operate(a, b, True)
elif '-' in expr:
a, b = expr.split('-')
return operate(a, b, False)
else:
return get_pos_val(get_pos(expr))
return int(cell)
# 执行加减运算
def operate(a, b, is_add):
try:
val_a = get_pos_val(get_pos(a)) if a[0].isalpha() else int(a)
val_b = get_pos_val(get_pos(b)) if b[0].isalpha() else int(b)
return val_a + val_b if is_add else val_a - val_b
except:
return 0
# 获取并更新位置的值
def get_pos_val(pos):
row, col = pos
cell_key = (row, col)
# 如果已经计算过,直接返回缓存值
if cell_key in cache:
return cache[cell_key]
try:
val = get_cell_val(table[row][col])
table[row][col] = str(val)
cache[cell_key] = val
return val
except:
return 0
try:
# 计算选中区域的和
r1, c1 = get_pos(start)
r2, c2 = get_pos(end)
total = 0
for i in range(r1, r2 + 1):
for j in range(c1, c2 + 1):
try:
total += get_cell_val(table[i][j])
except:
continue
return total
except:
return 0
if __name__ == "__main__":
print(solve())
#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
using namespace std;
class Solution {
vector<vector<string>> table;
unordered_map<string, int> cache;
public:
// 解析Excel坐标
pair<int,int> getPos(string cell) {
int col = cell[0] - 'A';
int row = stoi(cell.substr(1)) - 1;
return {row, col};
}
// 计算单元格值
int getCellVal(string cell) {
if(cell[0] == '=') {
string expr = cell.substr(1);
size_t pos;
if((pos = expr.find('+')) != string::npos) {
string a = expr.substr(0, pos);
string b = expr.substr(pos + 1);
return operate(a, b, true);
} else if((pos = expr.find('-')) != string::npos) {
string a = expr.substr(0, pos);
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
算法刷题笔记 文章被收录于专栏
本专栏收集并整理了一些刷题笔记