——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;
}
}
参考资料:无