UVa 196 电子表格

题意:给定一些电子表格,每个单元格里要么是整数要么是公式,公式是=号开头的,用+号连接的字符串。公式中要用到其他单元格的值,而要用到的其他单元格,可能还是个公式。但可以保证,不会形成单元格的环形的引用。其中,行的标号范围是从1到999,列的标号范围是从A到ZZZ。要求在输出的时候将公式替换为数值。

思路:很容易可以看到这和拓扑排序有关,一个单元格值的计算必须要在另一个的之前完成。但是这里没有必要进行拓扑排序。只需要在dfs访问的时候,递归地进行dfs即可。  中间错了几下,如注释部分的代码内容。其中第二个错误尤为严重,因为strchr(str, ch), 如果在sp=p后,传入参数的不是sp+1而是sp,那传入的参数相当于是空串~

小结:1. 取字符串中的内容。取如“=A1+A2+B3+C4”中的A1、A2等内容,代码如88-97行。

2. 进制的转化。将A、B、...、ZZZ转化为整数,代码如106行的alphatoint函数,重点是for循环中的简洁代码。

Code:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>

int dfs(char* sp);
int alphatoint(char *r);
void solve(int row,int col);

char* sheet[1000][18300];
char str[100];

int main()
{
  //freopen("196.in","r",stdin);
  //freopen("196.out","w",stdout);

  int num;
  scanf("%d",&num);
  while(num-->0)
  {
    int col,row;
    scanf("%d%d",&col,&row);
    for(int i=1;i<=row;++i)
     for(int j=1;j<=col;++j)
     {
       scanf("%s",str);
       char* c=(char*)malloc(strlen(str)+1);
       if(c==NULL) printf("false\n");
       sheet[i][j]=c;
       strcpy(sheet[i][j],str);
     }
    solve(row,col);
    //print
    for(int i=1;i<=row;++i)
    {
     for(int j=1;j<col;++j)
     {
       printf("%s ",sheet[i][j]);
     }
     //printf("%s\n",sheet[i][col-1]);
     printf("%s\n",sheet[i][col]);
    }
    //free-pointer
    for(int i=1;i<=row;++i)
     for(int j=1;j<=col;++j)
     {
       if(sheet[i][j]!=NULL) { free(sheet[i][j]); sheet[i][j]=NULL;}
     }
  }
  return 0;
}

void solve(int row,int col)
{
  for(int i=1;i<=row;++i)
   for(int j=1;j<=col;++j)
   {
     dfs(sheet[i][j]);
   }
}

int dfs(char* sp)
{
  if(sp[0]!='=')
  {//不是公式
    if(isdigit(sp[0]))
    {
      return atoi(sp);
    }
    else//递归调用时的A1、A2等单元格名称
    {
      int n=0;
      while(isalpha(sp[n])) n++;
      char c[4];
      strncpy(c,sp,n);
      c[n]='\0';
      char r[4];
      strcpy(r,sp+n);
      int co=alphatoint(c);
      int ro=atoi(r);
      return dfs(sheet[ro][co]);
    }
  }
  char* dp=sp;
  char* ep=(char*)malloc(strlen(sp)+1-1);
  int cnt=0;
  char* p=strchr(sp,'+');
  while(p!=NULL)
  {
    *p='\0';
    strcpy(ep,sp+1);
    cnt=cnt+dfs(ep);
    sp=p;
    //p=strchr(sp,'+');
    p=strchr(sp+1,'+');
  }
  strcpy(ep,sp+1);
  cnt=cnt+dfs(ep);
  sprintf(dp,"%d",cnt);
  free(ep);
  ep=NULL;
  return cnt;
}

int alphatoint(char *r)
{
  int cnt=0;
  int len=strlen(r);
  for(int i=0;i<len;++i)
  {
    cnt=cnt*26+(r[i]-'A'+1);
  }
  return cnt;
}
时间: 2024-11-02 02:44:35

UVa 196 电子表格的相关文章

Spreadsheet Calculator 电子表格计算器 (Uva 215)

原题:https://uva.onlinejudge.org/external/2/215.pdf 有一个M x N的表格,每个单元格是个数字或者表达式.表达式由单元格编号和+ - 号组成 输出单元格的结果 思路:用dfs判断有向图环的问题 1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <utility> 5 #include <cstring>

uva 512 追踪电子表格中的单元格

 Spreadsheet Tracking  Data in spreadsheets are stored in cells, which are organized in rows (r) and columns (c). Some operations on spreadsheets can be applied to single cells (r,c), while others can be applied to entire rows or columns. Typical cel

[题解]UVa 11082 Matrix Decompressing

开始眨眼一看怎么也不像是网络流的一道题,再怎么看也觉得像是搜索.不过虽然这道题数据范围很小,但也不至于搜索也是可以随随便便就可以过的.(不过这道题应该是special judge,因为一题可以多解而且题目中然而并没有什么要求,所以说可以考虑思考一下这道题有木有什么"套路"之类的通法) 比如说有这么一组数据 原矩阵 1 2 3 4 7 8 9 5 6 输入 3 3 6 25 45 14 28 45 然后将每一行的和写在每一列对应的行上(很明显有问题) 6 0 0 19 0 0 20 0

UVA 11324 The Largest Clique (强连通分量缩点,图DP)

题目: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=25&page=show_problem&problem=2299 题意: 给你一个有向图,求一个点集合的最大大小,使得此点集合中对于任意点对(u,v),有从u到v或者从v到u的边 方法: 先找强连通分量缩点,每个强连通分量显然满足条件,然后在缩点后的图中找到一条权值最大的路径,权值为此路径的点权之和,点权为这个

网页中模拟Excel电子表格实例分享

原文来自http://www.6excel.com/doc/20049 一.电子表格中用到的快捷键: ← → ↑ ↓  :左,右,上,下 Home :当前行的第一列 End  :当前行的最后一列 Shift+Home :表格的第一列 Shift+End:表格的最后一列 如图: 代码如下: <%@ page language="java" pageEncoding="UTF-8"%><html>  <head>    <tit

Excel 电子表格文件格式剖析

Excel 电子表格文件格式,这种Excel和其他的Excel是不同的.他的本质上是一个Xml文件(用英文版的UtraEdit可以看到),所以他可以保存任何符号的字符,包括&(它在Xml文件中是一种特殊字符.所以用aspose等工具是不能读取这种字符的). 反过来说,我们从中可以得到一种快速生成带有多个Worksheet的Workbook的Excel,从xml文件处理的个角度入手. <?xml version="1.0"?><?mso-application

uva 704

自己之前的不见了.. 这题是双向广搜即可过.. 1 // Colour Hash (色彩缤纷游戏) 2 // PC/UVa IDs: 110807/704, Popularity: B, Success rate: average Level: 3 3 // Verdict: Accepted 4 // Submission Date: 2011-08-28 5 // UVa Run Time: 0.048s 6 // 7 // 版权所有(C)2011,邱秋.metaphysis # yeah

Fast Matrix Operations(UVA)11992

UVA 11992 - Fast Matrix Operations 给定一个r*c(r<=20,r*c<=1e6)的矩阵,其元素都是0,现在对其子矩阵进行操作. 1 x1 y1 x2 y2 val 表示将(x1,y1,x2,y2)(x1<=x2,y1<=y2)子矩阵中的所有元素add上val: 2 x1 y1 x2 y2 val 表示将(x1,y1,x2,y2)(x1<=x2,y1<=y2)子矩阵中的所有元素set为val: 3 x1 y1 x2 y2 val 表示输

UVa 568 Just the Facts

A过去后看了一下别人的解法,发现除了打表还有一种数论的方法. 分析一下阶乘后面的0是怎么出现的呢,当然是2乘5得到的. 我们将1~N先放在一个数组里面. 从数组第一个元素开始,先统计一下N!中因子为5的个数记为count,将其除去,然后再除去count个2.这样一来的话把所有元素乘起来后就不会出现10的倍数了. 当然并不是真正的乘起来,那样的话肯定是要溢出的,因为只关心最后一位数,所以每次乘完后求10的余数即可. 我的做法是打表,因为题目里给了N <= 10000的条件限制,所以可以把1~100