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

接下来在第2、3、5行前各插入一个空行,然后在第3列前插入一个空列,会得到如图4- 3所示结果。

你的任务是模拟这样的n个操作。具体来说一共有5种操作:

  EX r1 c1 r2 c2交换单元格(r1,c1),(r2,c2)。

  <command>A x1 x2 … xA 插入或删除A行或列(DC-删除列,DR-删除行,IC-插入 列,IR-插入行,1≤A≤10)。

在插入/删除指令后,各个x值不同,且顺序任意。接下来是q个查询,每个查询格式 为“r c”,表示查询原始表格的单元格(r,c)。对于每个查询,输出操作执行完后该单元格的新 位置。输入保证在任意时刻行列数均不超过50。

【分析】

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

(直接上代码,不是很难理解)

  1. #include<stdio.h>
  2. #include<string.h>
  3. #define maxd 100
  4. #define BIG 10000
  5. int r, c, n, d[maxd][maxd], d2[maxd][maxd], ans[maxd][maxd], cols[maxd];
  6. void copy(char type, int p, int q) {
  7. if(type == 'R') {
  8. for(int i = ; i <= c; i++)
  9. d[p][i] = d2[q][i];
  10. }
  11. else {
  12. for(int i = ; i <= r; i++)
  13. d[i][p] = d2[i][q];
  14. }
  15. }
  16. void del(char type) {
  17. memcpy(d2, d, sizeof(d));
  18. int cnt = type == 'R' ? r : c, cnt2 = ;
  19. for(int i = ; i <= cnt; i++) {
  20. if(!cols[i]) copy(type, ++cnt2, i);
  21. }
  22. if(type == 'R') r = cnt2; else c = cnt2;
  23. }
  24. void ins(char type) {
  25. memcpy(d2, d, sizeof(d));
  26. int cnt = type == 'R' ? r : c, cnt2 = ;
  27. for(int i = ; i <= cnt; i++) {
  28. if(cols[i]) copy(type, ++cnt2, );
  29. copy(type, ++cnt2, i);
  30. }
  31. if(type == 'R') r = cnt2; else c = cnt2;
  32. }
  33. int main() {
  34. int r1, c1, r2, c2, q, kase = ;
  35. char cmd[];
  36. memset(d, , sizeof(d));
  37. while(scanf("%d%d%d", &r, &c, &n) == && r) {
  38. int r0 = r, c0 = c;
  39. for(int i = ; i <= r; i++)
  40. for(int j = ; j <= c; j++)
  41. d[i][j] = i*BIG + j;
  42. while(n--) {
  43. scanf("%s", cmd);
  44. if(cmd[] == 'E') {
  45. scanf("%d%d%d%d", &r1, &c1, &r2, &c2);
  46. int t = d[r1][c1]; d[r1][c1] = d[r2][c2]; d[r2][c2] = t;
  47. }
  48. else {
  49. int a, x;
  50. scanf("%d", &a);
  51. memset(cols, , sizeof(cols));
  52. for(int i = ; i < a; i++) { scanf("%d", &x); cols[x] = ; }
  53. if(cmd[] == 'D') del(cmd[]); else ins(cmd[]);
  54. }
  55. }
  56. memset(ans, , sizeof(ans));
  57. for(int i = ; i <= r; i++)
  58. for(int j = ; j <= c; j++) {
  59. ans[d[i][j]/BIG][d[i][j]%BIG] = i*BIG+j;
  60. }
  61. if(kase > ) printf("\n");
  62. printf("Spreadsheet #%d\n", ++kase);
  63. scanf("%d", &q);
  64. while(q--) {
  65. scanf("%d%d", &r1, &c1);
  66. printf("Cell data in (%d,%d) ", r1, c1);
  67. if(ans[r1][c1] == ) printf("GONE\n");
  68. else printf("moved to (%d,%d)\n", ans[r1][c1]/BIG, ans[r1][c1]%BIG);
  69. }
  70. }
  71. return ;
  72. }

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

  1. #include<stdio.h>
  2. #include<string.h>
  3. #define maxd 10000
  4. struct Command {
  5. char c[];
  6. int r1, c1, r2, c2;
  7. int a, x[];
  8. } cmd[maxd];
  9. int r, c, n;
  10. int simulate(int* r0, int* c0) {
  11. for(int i = ; i < n; i++) {
  12. if(cmd[i].c[] == 'E') {
  13. if(cmd[i].r1 == *r0 && cmd[i].c1 == *c0) { *r0 = cmd[i].r2; *c0 = cmd[i].c2; }
  14. else if(cmd[i].r2 == *r0 && cmd[i].c2 == *c0) { *r0 = cmd[i].r1; *c0 = cmd[i].c1; }
  15. }
  16. else {
  17. int dr = , dc = ;
  18. for(int j = ; j < cmd[i].a; j++) {
  19. int x = cmd[i].x[j];
  20. if(cmd[i].c[] == 'I') {
  21. if(cmd[i].c[] == 'R' && x <= *r0) dr++;
  22. if(cmd[i].c[] == 'C' && x <= *c0) dc++;
  23. }
  24. else {
  25. if(cmd[i].c[] == 'R' && x == *r0) return ;
  26. if(cmd[i].c[] == 'C' && x == *c0) return ;
  27. if(cmd[i].c[] == 'R' && x < *r0) dr--;
  28. if(cmd[i].c[] == 'C' && x < *c0) dc--;
  29. }
  30. }
  31. *r0 += dr; *c0 += dc;
  32. }
  33. }
  34. return ;
  35. }
  36. int main() {
  37. int r0, c0, q, kase = ;
  38. while(scanf("%d%d%d", &r, &c, &n) == && r) {
  39. for(int i = ; i < n; i++) {
  40. scanf("%s", cmd[i].c);
  41. if(cmd[i].c[] == 'E') {
  42. scanf("%d%d%d%d", &cmd[i].r1, &cmd[i].c1, &cmd[i].r2, &cmd[i].c2);
  43. }
  44. else {
  45. scanf("%d", &cmd[i].a);
  46. for(int j = ; j < cmd[i].a; j++) scanf("%d", &cmd[i].x[j]);
  47. }
  48. }
  49. if(kase > ) printf("\n");
  50. printf("Spreadsheet #%d\n", ++kase);
  51. scanf("%d", &q);
  52. while(q--) {
  53. scanf("%d%d", &r0, &c0);
  54. printf("Cell data in (%d,%d) ", r0, c0);
  55. if(!simulate(&r0, &c0)) printf("GONE\n");
  56. else printf("moved to (%d,%d)\n", r0, c0);
  57. }
  58. }
  59. return ;
  60. }

踪电子表格中的单元格(Spreadsheet Tracking, ACM/ICPC World Finals 1997, UVa512)的更多相关文章

  1. UVa512 追踪电子表格中的单元格

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  2. 4_5 追踪电子表格中的单元格(UVa512)(选做)

    在电子表格中的数据都存储在单元格中,它是按行和列(R)(C).一些在电子表格上的操作可以应用于单个单元格(研发),而其他的可以应用于整个行或列.典型的单元操作包括插入和删除行或列和交换单元格内容.一些 ...

  3. 如何把Excel中的单元格等对象保存成图片

    对于Excel中的很多对象,比如单元格(Cell),图形(shape),图表(chart)等等,有时需要将它们保存成一张图片.就像截图一样. 最近做一个Excel相关的项目,项目中遇到一个很变态的需求 ...

  4. winform中dataGridView单元格根据值设置新值,彻底解决绑定后数据类型转换的困难

    // winform中dataGridView单元格在数据绑定后,数据类型更改困难,只能迂回实现.有时候需要将数字变换为不同的文字描述,就会出现int32到string类型转换的异常,借助CellFo ...

  5. 读取Excel文件中的单元格的内容和颜色

    怎样读取Excel文件中的单元格的内容和颜色 先创建一个Excel文件,在A1和A2中随意输入内容,设置A1的字体颜色为红色,A2的背景为黄色.需要 using Excel = Microsoft.O ...

  6. 【表格设置】HTML中合并单元格,对列组合应用样式,适应各浏览器的内容换行

    1.常用表格标签 普通    <table>           |           <tr>          |           |          <th ...

  7. WPF备忘录(3)如何从 Datagrid 中获得单元格的内容与 使用值转换器进行绑定数据的转换IValueConverter

    一.如何从 Datagrid 中获得单元格的内容 DataGrid 属于一种 ItemsControl, 因此,它有 Items 属性并且用ItemContainer 封装它的 items. 但是,W ...

  8. (很难啊)如何实时获取DBGrid 中当前单元格输入的内容? [问题点数:100分,结帖人yifawu100]

    如何获取DBGrid 中当前单元格输入的内容? 还没输入完成,我想实时获取 Cell中的内容,以便作其他处理,用什么事件呢? 所以Field的Onchange事件是没用的. DBGrid1.Selec ...

  9. 如何实时获取DBGrid 中当前单元格输入的内容?

    如何获取DBGrid 中当前单元格输入的内容? 还没输入完成,我想实时获取 Cell中的内容,以便作其他处理, 用什么事件呢? 所以Field的Onchange事件是没用的. 这个问题简单啊,每输入1 ...

随机推荐

  1. 利用rman自己主动备份转储spfile

    利用rman自己主动备份转储spfile [情景简单介绍] 生产环境丢失了server的參数文件,rman已开启自己主动备份设置. [操作过程简述] ----启动rman $rman target / ...

  2. 0x0118消息就是WM_SYSTIMER

    http://social.msdn.microsoft.com/Forums/vstudio/en-US/c0f9bac9-d211-4b8b-ba99-f5a0ed0d2e0a/what-is-w ...

  3. 特征选择--->卡方选择器

    特征选择(Feature Selection)指的是在特征向量中选择出那些“优秀”的特征,组成新的.更“精简”的特征向量的过程.它在高维数据分析中十分常用,可以剔除掉“冗余”和“无关”的特征,提升学习 ...

  4. redhat6 改 centos yum 源

    **redhat的yum在线更新是收费的,如果没有注册的话不能使用,如果要使用,需将redhat的yum卸载后,重启安装其他yum源,再配置其他源.** 本文包括配置本地源及第三方源.第三方源包括:网 ...

  5. sort与sorted的区别

    描述 我们需要对List进行排序,Python提供了两个方法对给定的List L进行排序 :         方法1.用对List的成员函数sort进行排序        方法2.用内置函数sorte ...

  6. vue中时间控件绑定多个输入框

    首先去下载laydate时间控件,引入到相应的模板中 <input type="text" val-required="" value="&qu ...

  7. [Swift通天遁地]五、高级扩展-(7)UIView(视图类型)的各种扩展方法

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  8. [Swift通天遁地]九、拔剑吧-(17)创建一个三维折叠样式的页面展开效果

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  9. asp.net MVC ajax 请求参数前台加密后台解密

    最近有一个需求要求页面查询数据库,查询内容保存到excel里面作为附件加密打包下载.查询的sql作为参数传入后台,实现加密提交.这里做个记录,后面用到直接来拿. 控制器 public ActionRe ...

  10. 绑定树tree 的后台方法

    #region 获取部门列表树集合         /// <summary>         /// 获取部门列表树集合         /// </summary>     ...