UVa512追踪电子表格中的单元格题解

2023-12-06 06:52

本文主要是介绍UVa512追踪电子表格中的单元格题解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 题目

有一个r行c列(1≤r,c≤50)的电子表格,行从上到下编号为1~r,列从左到右编号为 1~c。如图(a)所示,如果先删除第1、5行,然后删除第3,6,7,9列,结果如图(b)所示。

接下来在第2、3、5行前各插入一个空行,然后在第3列前插入一个空列, 会得到如图(e)的结果。 你的任务是模拟这样的n个操作。具体来说一共有5种操作:

EX r1 c1 r2 c2交换单元格(r1,c1),(r2,c2)
Ax1x2…xA插入或删除A行或列(DC-删除列,DR-删除行,IC插入列,IR-插入行,1≤A≤10)。
在插入删除指令后,各个x值不同,且顺序任意。接下来是q个查询,每个查询格 为“r c”,表示查询原始表格的单元格(r,c)。对于每个查询,输出操作执行完后该单元格 新位置。输入保证在任意时刻行列数均不超过50。

图表从上到下从左到右分别为图(a)-(e),图可在

追踪电子表格中的单元格 Spreadsheet Tracking - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)中查看

输入输出样例

输入

7 9
5
DR 2 1 5
DC 4 3 6 7 9
IC 1 3
IR 2 2 4
EX 1 2 6 5
4
4 8
5 5
7 8
6 5
0 0

输出

Spreadsheet #1
Cell data in (4,8) moved to (4,6)
Cell data in (5,5) GONE
Cell data in (7,8) moved to (7,6)
Cell data in (6,5) moved to (1,2)

       第一种思路就是首先模拟操作,算出最后的电子表格,然后再每次查询时直接在电子表格中找到所求的单元格。

#include<stdio.h>
#include<string.h>
#define maxd 100
#define BIG 10000
int r,c,n,d[maxd][maxd],d2[maxd][maxd],ans[maxd][maxd],cols[maxd];//分别表示行,列,操作数,原始数据矩阵,临时矩阵
//最终变换矩阵,记录删除插入操作的矩阵 
void copy(char type,int p,int q){int i;//p<q if(type=='R'){for(i=1;i<=c;i++){d[p][i]=d2[q][i];}}else{for(i=1;i<=r;i++){d[i][p]=d2[i][q];}}
}
void del(char type){//删除操作其实就是将后面的行往前提一行,覆盖前一行 memcpy(d2,d,sizeof(d));int cut=type=='R'?r:c,cut2=0;int i;for(i=1;i<=cut;i++){if(!cols[i]){copy(type,++cut2,i);}}if(type=='R'){r=cut2;}else{c=cut2;}
}
void ins(char type){//插入相当于从前面拿一行放到指定的行前面 memcpy(d2,d,sizeof(d));int cut=type=='R'?r:c,cut2=0;int i;for(i=1;i<=cut;i++){if(cols[i]){copy(type,++cut2,0);}copy(type,++cut2,i);}
}
int main(){int r1,r2,c1,c2,q,kase=0;//分别定义要交换的两个位置的行列数 char cmd[10];//定义命令 memset(d,0,sizeof(d));//初始化原始矩阵while(scanf("%d%d%d",&r,&c,&n)==3&&r){int r0=r,c0=c;int i,j;for(i=1;i<=r;i++){//计算矩阵的值 for(j=1;j<=c;j++){d[i][j]=i*BIG+j;}}while(n--){//依次处理每一个命令 scanf("%s",cmd);if(cmd[0]=='E'){//交换命令,交换两个位置的值 scanf("%d%d%d%d",&r1,&r2,&c1,&c2);int t=d[r1][c1];d[r1][c1]=d[r2][c2];d[r2][c2]=t;}else{int a,x;scanf("%d",&a);//删除或者插入操作的次数 memset(cols,0,sizeof(cols));int i;for(i=0;i<a;i++){scanf("%d",&x);//记录要操作的行或者列 cols[x]=1;//把要操作的位置记为1 }if(cmd[1]=='D'){del(cmd[1]);}else{ins(cmd[1]);}}}memset(ans,0,sizeof(ans));for(i=1;i<=r;i++){for(j=1;j<=c;j++){ans[d[i][j]/BIG][d[i][j]%BIG]=i*BIG+j;}}if(kase>0){printf("\n");}printf("Spreadsheet #%d\n",++kase);scanf("%d",&q);//要查询的次数while(q--){scanf("%d%d",&r1,&c1);//要查询的位置printf("Cell data in (%d,%d)",r1,c1);if(ans[r1][c1]==0){printf("GONE\n");} else{printf("moved to (%d,%d)\n",ans[r1][c1]/BIG,ans[r1][c1]%BIG);}} }return 0; 
}               

       第二种思路是将所有操作保存,然后对于每一个查询重新执行每个操作,但不需要计算整个电子表格的变化,而只需关注所查询的单元格的位置变化。对于题目给定的规模来说,这个方法不仅更好些,而且效率更高。

#include<stdio.h>
#include<string.h>
#define maxd 10000
struct Command{char c[5];int r1,r2,c1,c2;int a,x[20];
}cmd[maxd];
int r,c,n;
int simulate(int* r0,int* c0){int i;for(i=0;i<n;i++){if(cmd[i].c[0]=='E'){//如果是交换且涉及到查询位置的话,直接将交换后的位置赋值给它,其他的交换不操作 if(cmd[i].r1==*r0&&cmd[i].c1==*c0){*r0=cmd[i].r2;*c0=cmd[i].c2;}else if(cmd[i].r2==*r0&&cmd[i].c2==*c0){*r0=cmd[i].r1;*c0=cmd[i].c1;}}else{int dr=0,dc=0;//定义行列的移动数int j;for(j=0;j<cmd[i].a;j++){//处理每一次操作 int x=cmd[i].x[j];//记录每一次操作的行或者列if(cmd[i].c[0]=='I'){if(cmd[i].c[1]=='R'&&x<=*r0){//如果在查询的位置前面有插入操作,直接将执行的插入操作的行数或列数加上即可 dr++;}if(cmd[i].c[1]=='C'&&x<=*c0){dc++;}} else{//如果在查询的位置前面有删除操作,直接将删除的行数或列数减去,如果正好是查询的位置直接删除 if(cmd[i].c[1]=='R'&&x==*r0){return 0;}if(cmd[i].c[1]=='C'&&x==*c0){return 0;}if(cmd[i].c[1]=='R'&&x<*r0){dr--;}if(cmd[i].c[1]=='C'&&x<*c0){dc--;}}*r0+=dr;*c0+=dc;} }}
}   
int main(){int r0,c0,q,kase=0;//r0,c0要查询的行和列 while(scanf("%d%d%d",&r,&c,&n)==3 && r){int i;for(i=0;i<n;i++){scanf("%s",cmd[i].c);//每种操作命令 }if(cmd[i].c[0]=='E'){scanf("%d%d%d%d",&cmd[i].r1,&cmd[i].c1,&cmd[i].r2,&cmd[i].c2);}else{scanf("%d",&cmd[i].a);//几次操作 int j;for(j=0;j<cmd[i].a;j++){scanf("%d",&cmd[i].x[j]);}}if(kase>0){printf("\n");}printf("Spreadsheet #%d\n",++kase);scanf("%d",&q);while(q--){scanf("%d%d",&r0,&c0);//查询printf("Cell data in (%d,%d)",r0,c0);if(!simulate(&r0,&c0)){printf("GONE\n");} else{printf("moved to (%d,%d)",r0,c0);}}}return 0;
}            

这篇关于UVa512追踪电子表格中的单元格题解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/460860

相关文章

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

C - Word Ladder题解

C - Word Ladder 题解 解题思路: 先输入两个字符串S 和t 然后在S和T中寻找有多少个字符不同的个数(也就是需要变换多少次) 开始替换时: tips: 字符串下标以0开始 我们定义两个变量a和b,用于记录当前遍历到的字符 首先是判断:如果这时a已经==b了,那么就跳过,不用管; 如果a大于b的话:那么我们就让s中的第i项替换成b,接着就直接输出S就行了。 这样

【秋招笔试】9.07米哈游秋招改编题-三语言题解

🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 大厂实习经历 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 🍒 本专栏已收集 100+ 套笔试题,笔试真题 会在第一时间跟新 🍄 题面描述等均已改编,如果和你笔试题看到的题面描述

LeetCode 第414场周赛个人题解

目录 Q1. 将日期转换为二进制表示 原题链接 思路分析 AC代码 Q2. 范围内整数的最大得分 原题链接 思路分析 AC代码 Q3. 到达数组末尾的最大得分 原题链接 思路分析 AC代码 Q4. 吃掉所有兵需要的最多移动次数 原题链接 思路分析 AC代码 Q1. 将日期转换为二进制表示 原题链接 Q1. 将日期转换为二进制表示 思路分析

牛客小白月赛100部分题解

比赛地址:牛客小白月赛100_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ A.ACM中的A题 #include<bits/stdc++.h>using namespace std;#define ll long long#define ull = unsigned long longvoid solve() {ll a,b,c;cin>>a>>b>

如何在Excel中根据单元格内容作MSnbsp;…

上篇文章,我们介绍了INDEX+SMALL+IF+ROW的数组公式组合,也就是说只要在IF中通过条件的构造,基本上就可以想提取什么条件的数据都可以,数据查询肯定得心应手。 但是,我们一起强调函数公式不是万能的,尤其是数组公式在海量数据面前,既是软肋也是硬伤,而且构造这个函数组合还需要你要具备或者能理解简单数组公式逻辑,对于在函数公式方面没有深究的人,自然是一头雾水。当然,就像“数据透视表”一样,

jqgrid设置单元格可编辑

1 在单元格的属性列设置为editable。 2 点击编辑按钮的时候,触发某一行设置为edit的状态。 jQuery("#rowed4").jqGrid({url:'server.php?q=2',datatype: "json",colNames:['Inv No','Date', 'Client', 'Amount','Tax','Total','Notes'],colModel

P2858 [USACO06FEB] Treats for the Cows G/S 题解

P2858 题意 给一个数组。每天把最左或者最右的东西卖掉,第 i i i个东西,第 d a y day day天卖出的价格是 a [ i ] ∗ d a y a[i]*day a[i]∗day。 记忆化搜索 void dfs(int l,int r,int day,ll sum){if(v[l][r]>=sum)return;v[l][r]=sum;if(l>r)//这就是dp答案{

【Markdown】如何在Markdown中合并单元格

Markdown语法本身不包含复杂表格的插入,但是可以使用html语法来实现。 水平单元格的合并:基于colspan属性,即使一个单元格占多列的空间纵向单元格的合并:基于rowspan属性,即使一个单元格占多行的空间 要想MarkDown中插入复杂表格时,可以先在word或excel中把表格写好,然后在如下网站进行转化为标记对形式: http://pressbin.com/tools/exc