给出一个R行C列的电子表格,行编号A~T, 列编号0~9,按照行优先的顺序给出各个单元格。每个单元格可能是整数也可能是引用了其他单元格的表达式,表达式仅由加减号、非负整数、单元格名称组成,没有括号,且以单元格名称开头,内部不含空白符,最多75个字符。要求计算出所有单元格的值,如果所有的单元格都能成功计算出结果,那么将这张表格输出来,每个元素6个占字符的宽度,对齐。如果出现单元格循环引用以致无法输出,则将无法正常计算出结果的单元格及其表达式输出,仍按照行优先的顺序输出。详细格式参见样例。
关键是陷入循环结构的处理,类似拓扑排序
但是在输出格式与处理字符串输入(没有意识到字符串中多位数字被拆)耗费大量时间
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cctype>
#include<vector>
#include<cmath>
#include<iomanip>
using namespace std;
const int maxr = 25;
const int maxc = 15;
const int INF = 1e5; //代替错误指示符号
int sheet[maxr * maxc];
int done[maxr * maxc];
vector<int> G[maxr * maxc];
string s[maxr * maxc];
int dfs(int u)
{
done[u] = -1;
for (int i = 0; i < G[u].size(); i++)
{
int v = G[u][i];
int sign = 1;
if (v < 0)
{
sign = -1;
v = -v;
}
if (done[v] < 0)
return INF;
else if (done[v])
{
sheet[u] += sign * sheet[v];
continue;
}
int ans = dfs(v);
if (ans == INF)
{
return INF;
}
else
sheet[u] += sign * ans;
}
done[u] = 1;
return sheet[u];
}
int main()
{
int R, C;
while (scanf("%d %d", &R, &C) && R)
{
memset(sheet, 0, sizeof(sheet));
memset(G, 0, sizeof(G));
memset(done, 0, sizeof(done));
int cnt = 0; //二维化一维进行编号
for (int i = 1; i <= R*C;i++)//输入与建图
{
cin >> s[i];
cnt++;
if (s[i].size() == 1)
{
sheet[cnt] += s[i][0] - '0';
}
else
{
int n, m, flag = 0, flag1 = 1, num;
for (int j = 0; j < s[i].size(); j++)
{
if (isalpha(s[i][j]))
{
n = s[i][j] - 'A';
flag = 1;
}
else if (isdigit(s[i][j]) && flag)
{
m = s[i][j] - '0';
flag = 0;
num = C*n + m + 1;
G[cnt].push_back(flag1 * num); //G储序号,负数代表此运算符号
}
else if (s[i][j] == '-')
{
flag1 = -1;
}
else if (s[i][j] == '+')
{
flag1 = 1;
}
else if (isdigit(s[i][j]) && !flag)
{
int k = 1, num = 0;
num += (s[i][j] - '0');
while (isdigit(s[i][j + 1]))//注意字符串中数字不止一位数时
{
num = num * pow(10, k) + (s[i][j + 1] - '0') ;//sheet储子叶带符号值
j++;
k++;
}
sheet[cnt] += flag1 * num;
}
}
}
}
int flag = 1, ans;
for (int i = 1; i <= R*C; i++)
{
if (!done[i])
{
ans = dfs(i);
if (ans == INF)
{
printf("%c%d: ", (i-1) / C + 'A', (i-1)%C);
cout << s[i] << endl;
flag = 0;
}
}
else if (done[i] == -1)
{
printf("%c%d: ", (i - 1) / C + 'A', (i - 1) % C);
cout << s[i] << endl;
}
}
if (flag)
{
cout << " ";
for (int i = 0; i < C; i++)
{
cout << std::right << setw(6) <<i; //对齐
}
cout << endl;
cnt = 0;
for (int i = 0; i < R; i++)
{
printf("%c",'A' + i);
int first = 1;
for (int j = 0; j < C; j++)
{
cout << std::right << setw(6) <<sheet[++cnt];
}
cout << endl;
}
}
cout << endl;
}
}