1 条题解
-
0
题意分析
题目要求我们检测电子表格中单元格的循环依赖关系。每个单元格可能包含一个公式,该公式可以引用其他单元格的值。我们需要确定:
单元格定义:每个单元格以"RxxCxx=..."的形式定义,其中等号后面是表达式 表达式语法:支持加减乘除、括号、数字和其他单元格引用
循环检测:如果一个单元格直接或间接依赖于自身,则存在循环依赖
输出要求:为每个单元格输出其是否参与循环依赖
解题思路
问题建模 将电子表格建模为有向图: 节点:每个单元格 边:如果单元格A的公式引用了单元格B,则添加一条从B到A的边
循环检测算法 使用拓扑排序的思想检测循环: 计算每个节点的入度(被引用次数) 从入度为0的节点开始DFS遍历 遍历过程中减少相邻节点的入度 最终仍存在入度的节点即为循环依赖的节点
具体实现步骤 输入处理: 解析单元格定义 提取单元格间的引用关系 构建邻接表表示的有向图
拓扑排序: 初始化入度数组 使用DFS或BFS进行拓扑遍历 标记无法被遍历到的节点(存在循环)
结果输出: 根据拓扑排序结果输出每个单元格的状态
参考代码
#include <cstdio> #include <algorithm> #include <cstring> using namespace std; typedef long long ll; int head[410],tot,cell[410],deg[410],vis[410]; struct edge { int to,next; } G[500010]; int no[10000],ntot; char buf[100010]; void addedge(int x,int y){ G[++tot].to=y; G[tot].next=head[x]; head[x]=tot; ++deg[y]; } void dfs(int x){ if(vis[x]) return; vis[x]=true; for(int it=head[x];it;it=G[it].next){ int y=G[it].to; --deg[y]; if(deg[y]==0) dfs(y); } } int main(){ while(scanf("%s",buf)!=EOF){ int x=buf[1]*1000+buf[2]*100+buf[4]*10+buf[5]*1-53328; if(no[x]==0) {no[x]=++ntot;cell[ntot]=x;} x=no[x]; int l=strlen(buf); for(int i=7;i<l;i++){ if(buf[i]=='R'){ int y=buf[i+1]*1000+buf[i+2]*100+buf[i+4]*10+buf[i+5]*1-53328; if(no[y]==0) {no[y]=++ntot;cell[ntot]=y;} y=no[y]; addedge(y,x); } } } for(int i=1;i<=ntot;i++){ if(deg[i]==0) dfs(i); } for(int i=1;i<=ntot;i++){ if(deg[i]) printf("R%02dC%02d circular\n",cell[i]/100,cell[i]%100); else printf("R%02dC%02d ok\n",cell[i]/100,cell[i]%100); } }
- 1
信息
- ID
- 1321
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者