E卷-Excel单元格数值统计-200分

E卷-刷题笔记合集🔗

题目描述

Excel工作表中对选定区域的数值进行统计的功能非常实用。请实现一个类似的功能,对给定表格中选中区域的单元格进行求和统计。

单元格内容分为两种类型:

  1. 数字:非负整数,如 3、77
  2. 公式:以=开头,包含以下三种情况:
    • 等于某单元格的值,如 =B12
    • 两个单元格的加减运算,如 =C1-C2、C3+B2
    • 单元格和数字的加减运算,如 =B1+1、100-B2

输入格式

第一行输入两个整数 ,表示表格的行数和列数:

接下来 行,每行 个以空格分隔的字符串,表示表格的单元格内容。

最后一行输入一个字符串,表示选中区域,格式如 A1:C2。

输出格式

输出一个整数,表示选中区域各单元格中数字的累加总和。

  • 结果范围:

约束说明

  1. 公式内容保证合法:

    • 不存在 =C+1、=C1-C2+B3、=5、=3+5 等非法格式
    • 不存在循环引用,如 A1=B1+C1、C1=A1+B2
    • 不存在空格、括号
  2. 表格规则:

    • 行号范围:1~20
    • 列号范围:A~Z
    • 单元格B3对应values[2][1]
    • 单元格数值范围:[0,100]
  3. 选中区域规则:

    • 冒号左侧为左上角
    • 冒号右侧为右下角
    • 合法格式: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

题解

这道题的关键点在于:

  1. Excel坐标转换

    • 列号: A->0, B->1, C->2 (ASCII码减65)
    • 行号: 数字减1
  2. 公式解析

    • 提取操作数和运算符
    • 递归计算引用的单元格值
    • 更新计算结果
  3. 区域求和

    • 确定选中区域范围
    • 遍历计算每个单元格
    • 累加求和

实现思路:

  1. 定义辅助函数:

    • getPos: 解析Excel坐标
    • getCellVal: 计算单元格值
    • operate: 执行加减运算
  2. 主要步骤:

    • 读取表格数据
    • 解析选中区域
    • 遍历求和计算

时间复杂度:

参考代码

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%内容,订阅专栏后可继续查看/也可单篇购买

算法刷题笔记 文章被收录于专栏

本专栏收集并整理了一些刷题笔记

全部评论

相关推荐

仁者伍敌:难怪小公司那么挑剔,让你们这些大佬把位置拿了
点赞 评论 收藏
分享
评论
1
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务