UVA215-Spreadsheet Calculator(模拟+拓扑排序)

时间:2023-12-25 22:16:28

Problem UVA215-Spreadsheet Calculator

Accept:401  Submit:2013

Time Limit: 3000 mSec

UVA215-Spreadsheet Calculator(模拟+拓扑排序) Problem Description

A spreadsheet is a rectangular array of cells. Cells contain data or expressions that can be evaluated to obtain data. A “simple” spreadsheet is one in which data are integers and expressions are mixed sums and differences of integers and cell references. For any expression, if each cell that is referenced contains an integer, then the expression can be replaced by the integer to which the expression evaluates. You are to write a program which evaluates simple spreadsheets.

UVA215-Spreadsheet Calculator(模拟+拓扑排序) Input

Input consists of a sequence of simple spreadsheets. Each spreadsheet begins with a line specifying the number of rows and the number of columns. No spreadsheet contains more than 20 rows or 10 columns. Rows are labeled by capital letters A through T. Columns are labeled by decimal digits 0 through 9. Therefore, the cell in the first row and first column is referenced as A0; the cell in the twentieth row and fifth column is referenced as T4.
Following the specification of the number of rows and columns is one line of data for each cell, presented in row-major order. (That is, all cells for the first row come first, followed by all cells for the second row, etc.) Each cell initially contains a signed integer value or an expression involving unsigned integer constants, cell references, and the operators + (addition) and - (subtraction). If a cell initially contains a signed integer, the corresponding input line will begin with an optional minus sign followed by one or more decimal digits. If a cell initially contains an expression, its input line will contain one or more cell references or unsigned integer constants separated from each other by + and - signs. Such a line must begin with a cell reference. No expression contains more than 75 characters. No line of input contains leading blanks. No expression contains any embedded blanks. However, any line may contain trailing blanks.
The end of the sequence of spreadsheets is marked by a line specifying 0 rows and 0 columns.

UVA215-Spreadsheet Calculator(模拟+拓扑排序) Output

For each spreadsheet in the input, you are to determine the value of each expression and display the resulting spreadsheet as a rectangular array of numbers with the rows and columns appropriately labeled. In each display, all numbers for a column must appear right-justified and aligned with the column label.
Operators are evaluated left to right in each expression; values in cells are always less than 10000 in absolute value. Since expressions may reference cells that themselves contain expressions, the order in which cells are evaluated is dependent on the expressions themselves.
If one or more cells in a spreadsheet contain expressions with circular references, then the output for that spreadsheet should contain only a list of the unevaluated cells in row-major order, one per line, with each line containing the cell label, a colon, a blank, and the cell’s original expression.
A blank line should appear following the output for each spreadsheet.

UVA215-Spreadsheet Calculator(模拟+拓扑排序) Sample Input

2 2
A1+B1
5
3
B0-A1
3 2
A0
5
C1
7
A1+B1
B0+A1
0 0
 

UVA215-Spreadsheet Calculator(模拟+拓扑排序) Sample Ouput

      0     1
A     3     5
B     3    -2
A0: A0
B0: C1
C1: B0+A1
题解:一道模拟题,我一开始没理解题意,WA了两发,主要是没有考虑可以计算的数字表达式,考虑了之后就没有太大问题了。
这个题的递归函数框架其实是按照拓扑排序来写的,vis数组三种状态0,1,-1,分别表示未访问,正在访问,已访问。这样就可以轻松找环(dfs过程中遇到vis为-1的点就意味着找到了环)。
把环标记一下可以大大剪枝。
 #include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
using namespace std; const int Row = ,Cloumn = ;
const int maxl = ;
int vis[Row][Cloumn];
bool is_circle[Row][Cloumn];
int n,m; struct Point{
bool is_num;
int num;
char ss[];
Point(bool is_num = false,int num = ) :
is_num(is_num),num(num) {}
};
Point gra[Row][Cloumn]; bool dfs(int x,int y){
if(is_circle[x][y]) return false;
if(vis[x][y] == -){
gra[x][y].is_num = false;
is_circle[x][y] = true;
return false;
}
if(vis[x][y] == ) return true;
vis[x][y] = -;
int ans = ;
char *p = &gra[x][y].ss[];
int flag = ;
//bool IsNum = true;
for(int i = ;i < strlen(p);){
if(p[i] == '+'){
i++;
flag = ;
continue;
}
else if(p[i] == '-'){
i++;
flag = -;
continue;
}
if(isdigit(p[i])){
int temp;
sscanf(p+i,"%d",&temp);
ans += temp*flag;
while(isdigit(p[i])) i++;
}
else{
//IsNum = false;
int r = p[i]-'A',c = p[i+]-'';
i += ;
if(gra[r][c].is_num) ans += flag*gra[r][c].num;
else{
if(dfs(r,c)){
ans += flag*gra[r][c].num;
}
else{
gra[x][y].is_num = false;
is_circle[x][y] = true;
vis[x][y] = ;
return false;
}
}
}
}
gra[x][y].is_num = true;
gra[x][y].num = ans;
vis[x][y] = ;
return true;
} void output(){
printf(" ");
for(int i = ;i < m;i++){
printf("%6d",i);
}
printf("\n");
for(int i = ;i < n;i++){
printf("%c",i+'A');
for(int j = ;j < m;j++){
printf("%6d",gra[i][j].num);
}
printf("\n");
}
} int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
while(~scanf("%d%d",&n,&m) && (n||m)){
char str[];
memset(vis,,sizeof(vis));
memset(is_circle,false,sizeof(is_circle));
for(int i = ;i < n;i++){
for(int j = ;j < m;j++){
scanf("%s",str);
gra[i][j].is_num = false;
strncpy(gra[i][j].ss,str,sizeof(str));
}
}
for(int i = ;i < n;i++){
for(int j = ;j < m;j++){
if(gra[i][j].is_num) continue;
dfs(i,j);
}
}
bool ok = true;
for(int i = ;i < n;i++){
int j;
for(j = ;j < m;j++){
if(is_circle[i][j]){
ok = false;
break;
}
}
if(j != m) break;
}
if(ok){
output();
}
else{
for(int i = ;i < n;i++){
for(int j = ;j < m;j++){
if(is_circle[i][j]){
printf("%c%d: %s\n",i+'A',j,gra[i][j].ss);
}
}
}
}
printf("\n");
}
return ;
}