华为 OD 机测试 - Excel 单元格值统计(Python/JS/C/C++ 2024 年 E 卷 200 分) - VIII、C 算法源代码
最编程
2024-10-06 21:03:03
...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAX_ROWS 20
#define MAX_COLS 26
#define MAX_CELL_LEN 100
#define MAX_EXPR_LEN 1000
// 定义表格内容
char table[MAX_ROWS][MAX_COLS][MAX_CELL_LEN];
// 记忆化存储单元格值,初始化为未计算状态
long long memo_val[MAX_ROWS][MAX_COLS];
int memo_flag[MAX_ROWS][MAX_COLS] = {0};
// 表格的行数和列数
int rows, cols;
// 将单元格标识转换为行列索引
void cell_to_index(char *cell, int *row, int *col){
*col = 0;
int i = 0;
// 处理列(字母部分)
while(cell[i] && isalpha(cell[i])){
*col = (*col) * 26 + (toupper(cell[i]) - 'A' + 1);
i++;
}
// 处理行(数字部分)
char num_part[MAX_CELL_LEN];
int j = 0;
while(cell[i]){
num_part[j++] = cell[i++];
}
num_part[j] = '\0';
*row = atoi(num_part) -1;
*col = *col -1;
}
// 将行列索引转换为单元格标识
void index_to_cell(int row, int col, char *cell){
cell[0] = '\0';
col +=1;
char temp[10];
while(col >0){
int rem = (col -1) %26;
char c = 'A' + rem;
sprintf(temp, "%c", c);
strcat(cell, temp);
col = (col -1) /26;
}
char row_str[10];
sprintf(row_str, "%d", row +1);
strcat(cell, row_str);
}
// 解析并计算表达式
long long evaluate_expression(char *expr);
// 解析单个项,可能是单元格引用或数字
long long parse_term(char *term){
if(isalpha(term[0])){
int r, c;
cell_to_index(term, &r, &c);
return evaluate(r, c);
}
else{
return atoll(term);
}
}
// 计算单元格的值
long long evaluate(int row, int col){
// 如果已经计算过,直接返回
if(memo_flag[row][col]){
return memo_val[row][col];
}
char *content = table[row][col];
long long value =0;
if(content[0] != '='){
// 直接是数字
value = atoll(content);
}
else{
// 是公式,解析并计算表达式
char expr[MAX_EXPR_LEN];
strcpy(expr, content +1); // 去掉 '='
value = evaluate_expression(expr);
}
// 记忆化存储
memo_val[row][col] = value;
memo_flag[row][col] =1;
return value;
}
// 解析并计算表达式
long long evaluate_expression(char *expr){
int op_pos = -1;
char op = 0;
// 查找运算符的位置
for(int i=0; i<strlen(expr); i++){
if(expr[i] == '+' || expr[i] == '-'){
op_pos = i;
op = expr[i];
break;
}
}
if(op_pos == -1){
// 没有运算符,可能是单元格引用或数字
char term[MAX_CELL_LEN];
strcpy(term, expr);
return parse_term(term);
}
else{
// 分割表达式为左半部分和右半部分
char left[MAX_CELL_LEN];
strncpy(left, expr, op_pos);
left[op_pos] = '\0';
char right[MAX_CELL_LEN];
strcpy(right, expr + op_pos +1);
long long left_val = parse_term(left);
long long right_val = parse_term(right);
if(op == '+'){
return left_val + right_val;
}
else{
return left_val - right_val;
}
}
}
int main(){
// 读取行数和列数
scanf("%d %d", &rows, &cols);
// 读取表格内容
for(int i=0; i<rows; i++){
for(int j=0; j<cols; j++){
scanf("%s", table[i][j]);
}
}
// 读取统计区域
char range[20];
scanf("%s", range);
// 解析统计区域的起始和结束单元格
char *token = strtok(range, ":");
char start_cell[MAX_CELL_LEN];
char end_cell[MAX_CELL_LEN];
strcpy(start_cell, token);
token = strtok(NULL, ":");
strcpy(end_cell, token);
int start_r, start_c, end_r, end_c;
cell_to_index(start_cell, &start_r, &start_c);
cell_to_index(end_cell, &end_r, &end_c);
// 计算总和
long long total =0;
for(int r=start_r; r<=end_r; r++){
for(int c=start_c; c<=end_c; c++){
total += evaluate(r, c);
}
}
// 输出结果
printf("%lld\n", total);
return 0;
}