UVaOJ 196 - Spreadsheet


——by A Code Rabbit


Description

输入一张电子表格,请你把单元格填上的函数计算出来,填上数字输出。

函数的形式都是,其他单元格上的数字相加,并且保证没有求不出来的函数。


Types

Date Structure :: Graphs


Analysis

把单元格当作点,单元格之间的关系当作边,变成一张图。

这题的求解就变成了,去遍历一张图的每一个点,而函数单元格要在其参数走到之后才能走到。

所以拓扑排序,或者是暴力什么的,都可以。

但是要注意,虽然不知道测试数据怎么样,但是题目的数据规模有点吓人,是1000 * 1000的点。

如此多的点无法用一张邻接表来存储,需要把函数单元格映射到链表上,用链表来存储图的边。

这题的难点就是在输入表格的时候,如何用二维数组映射链表来存储(其实就是广义表)。

不过简单的地方就是,OJ上好似没有特别恶心的测试点(POJ上甚至明显WA的代码都可能AC)。


Solution

// UVaOJ 196
// Spreadsheet
// by A Code Rabbit

#include <cstdio>
#include <cstring>
#include <cctype>

const int LIMITS = 1234;
const int LIMITS_NODE = 1000000;

int t;

struct Cell {
    int value;
    int index;
};

Cell spreadsheet[LIMITS][LIMITS];
int n, m;

struct Node {
    int x;
    int y;
    int succ;
};

Node node[LIMITS_NODE];
int num_node;

bool IsLetter(char ch);
void Process(int x, int y, char* str);
int GetValue(int x, int y);

int main() {
    scanf("%d", &t);
    while (t--) {
        // INIT.
        num_node = 0;
        // Inputs.
        scanf("%d%d", &n, &m);
        getchar();
        for (int i = 1; i <= m; ++i) {
            for (int j = 1; j <= n; ++j) {
                char str[100];
                scanf("%s", str);
                Process(i, j, str);
            }
            getchar();
        }
        // Get the values of cells of the spreadsheet.
        for (int i = 1; i <= m; ++i) {
            for (int j = 1; j <= n; ++j) {
                if (spreadsheet[i][j].index != -1) {
                    GetValue(i, j);
                }
            }
        }
        // Outputs.
        for (int i = 1; i <= m; ++i) {
            for (int j = 1; j <= n - 1; ++j) {
                printf("%d ", spreadsheet[i][j].value);
            }
            printf("%d\n", spreadsheet[i][n]);
        }
    }

    return 0;
}

void Process(int x, int y, char* str) {
    if (str[0] != '=') {
        sscanf(str, "%d", &spreadsheet[x][y].value);
        spreadsheet[x][y].index = -1;
    } else {
        spreadsheet[x][y].index = num_node;
        int pos = 1;
        while (pos < strlen(str)) {
            if (isalnum(str[pos])) {
                Node& new_node = node[num_node];
                new_node.x = 0;
                new_node.y = 0;
                while (isalpha(str[pos])) {
                    new_node.y = new_node.y * 26 + str[pos] - 'A' + 1;
                    pos++;
                }
                while (isdigit(str[pos])) {
                    new_node.x = new_node.x * 10 + str[pos] - '0';
                    pos++;
                }
                
            }
            node[num_node].succ = num_node + 1;
            ++num_node;
            ++pos;
        }
        node[num_node - 1].succ = -1;
    }
}

int GetValue(int x, int y) {
    if (spreadsheet[x][y].index == -1) {
        return spreadsheet[x][y].value;
    } else {
        int sum = 0;
        int index = spreadsheet[x][y].index;
        while (index != -1) {
            sum += GetValue(node[index].x, node[index].y);
            index = node[index].succ;
        }
        spreadsheet[x][y].value = sum;
        spreadsheet[x][y].index = -1;
        return sum;
    }
}


下载PDF

参考资料:无


你可能感兴趣的:(UVaOJ 196 - Spreadsheet)