UVa 215 - Spreadsheet Calculator

时间限制:3.000秒

题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=151


  数据结构+模拟。

  给出一个R行C列的电子表格,行编号A~T, 列编号0~9,按照行优先的顺序给出各个单元格。每个单元格可能是整数也可能是引用了其他单元格的表达式,表达式仅由加减号、非负整数、单元格名称组成,没有括号,且以单元格名称开头,内部不含空白符,最多75个字符。要求计算出所有单元格的值,如果所有的单元格都能成功计算出结果,那么将这张表格输出来,每个元素6个占字符的宽度,对齐。如果出现单元格循环引用以致无法输出,则将无法正常计算出结果的单元格及其表达式输出,仍按照行优先的顺序输出。详细格式参见样例。

  按照题意模拟即可,需要注意的地方有表达式的读取以及数据结构的选用。

  这里先将表达式中数字部分先保存在表中,然后将表达式中对单元格的引用单独保存起来,读取全部输入之后dfs计算结果,如果循环则将对应单元格标记为计算失败,并将结果放入set中,最后输出即可。


#include 
   
   
    
    
#include 
    
    
     
     
#include 
     
     
      
      
#include 
      
      
       
       
#include 
       
       
         #include 
        
          #include 
         
           #include 
          
            using namespace std; int r, c, size; vector 
            
            
              > pt[256]; int ss[256]; string ss_s[256]; bool ok_all; set 
             
               put_false; bool ok[256]; bool vis[256]; int dfs(const int &pos) { if(!ok[pos]) { ok_all = false; return 0; } if(pt[pos].empty()) return ss[pos]; if(vis[pos]) { ok[pos] = false; ok_all = false; put_false.insert(pos); return 0; } vis[pos] = true; for(auto it = pt[pos].begin(); it != pt[pos].end(); ++it) { if(ok[it->first]) ss[pos] += (it->second) * dfs(it->first); if(!ok[it->first]) { ok[pos] = false; ok_all = false; put_false.insert(pos); } } pt[pos].clear(); return ss[pos]; } int main() { ios::sync_with_stdio(false); while(cin >> r >> c && r && c) { size = r * c; for(int i = 0; i != size; ++i) { pt[i].clear(); ss[i] = 0; string ele; cin >> ele; ss_s[i] = ele; vector 
              
                sign; if(ele[0] == '-') sign.push_back(-1); else sign.push_back(1); for(auto it = ele.begin(); it != ele.end(); ++it) { if(*it == '-') sign.push_back(-1), *it = ' '; else if(*it == '+') sign.push_back(1), *it = ' '; } istringstream line(ele); auto it = sign.begin(); while(line >> ele) { if(isdigit(ele[0])) { istringstream t(ele); int d; t >> d; ss[i] += d * (*it++); } else { int pos = (ele[0] - 'A') * c + ele[1] - '0'; pt[i].push_back(pair 
               
                 (pos, *it++)); } } } ok_all = true; put_false.clear(); for(int i = 0; i != size; ++i) ok[i] = true, vis[i] = false; for(int i = 0; i != size; ++i) dfs(i); if(!ok_all) { for(auto it = put_false.begin(); it != put_false.end(); ++it) cout << (char)(*it / c + 'A') << *it % c << ": " << ss_s[*it] << endl; } else { cout << ' '; for(int i = 0; i != c; ++i) cout << setw(6) << i; cout << endl; for(int i = 0; i != r; ++i) { cout << (char)(i + 'A'); for(int j = 0; j != c; ++j) cout << setw(6) << ss[i * c + j]; cout << endl; } } cout << endl; } } 
                
               
              
             
            
           
          
         
       
      
      
     
     
    
    
   
   

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值