例题 4-5 追踪电子表格中的单元格(Spreadsheet Tracking) UVa 512

来源:互联网 发布:淘宝买东西后怎么评价 编辑:程序博客网 时间:2024/05/21 18:50

题意:

有一个r行c列的电子表格,对其进行n个操作。操作类型分为5种:

1. 删除行 2. 删除列 3. 插入行 4. 插入列 5. 交换两个元素位置

输入初始查找位置,输出经过n个操作后,变更的位置

Input

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

#include<stdio.h>#include<string.h>#define maxd 10000struct Command{char c[5];//保存指令int r1, c1, r2, c2;//交换的两个坐标int a, x[20];// a 为当前指令行列变换操作次数 x[20] 存储的是相应指令集合}cmd[maxd];int r, c, n; //n为指令次数int simulate(int *r0, int *c0){for(int i = 0; i < n; i++ ){if(cmd[i].c[0] == 'E'){//交换操作if(*r0 == cmd[i].r1 && *c0 == cmd[i].c1){*r0 = cmd[i].r2;*c0 = cmd[i].c2;}else if(*r0 == cmd[i].r2 && *c0 == cmd[i].c2){*r0 = cmd[i].r1;*c0 = cmd[i].c1;}}else if(cmd[i].c[0] != 'E'){int dr = 0,dc = 0;//记录每组此操作r0, c0坐标变换情况for(int 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++;//才会影响r0, c0)}else if(cmd[i].c[0] == 'D'){if(cmd[i].c[1] == 'R' && x == *r0) return 0;//删除当前行、列if(cmd[i].c[1] == 'C' && x == *c0) return 0;//时直接返回 0if(cmd[i].c[1] == 'R' && x < *r0) dr--;(同上注意删除不能是本行列)if(cmd[i].c[1] == 'C' && x < *c0) dc--;}}*r0 += dr;//每组指令执行完毕后 更新此时 坐标状况*c0 += dc;}}return 1;}int main(){//freopen("C:\\Users\\zhangwei\\Desktop\\input.txt","r",stdin); int r0, c0, q, kcase = 0;while(scanf("%d%d%d",&r,&c,&n) == 3 && r != 0){for(int 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);for(int j = 0; j < cmd[i].a; j++ ){scanf("%d",&cmd[i].x[j]);} }}if(kcase++)printf("\n");printf("Spreadsheet #%d\n",kcase);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");elseprintf("moved to (%d,%d)\n", r0, c0); }}return 0;}

注意 :
(1)这里的所有操作都是基于最开始的表格,也就是对初始表格一次性执行所有操作得到的结果。
(2)题目 没有对初始表格进行操作 , 只是对 表格的坐标进行变换(根据指令集确定dr, dc )
(3)r0, c0 在每组指令执行完毕都会变化 此时就要更新 ,否则 若最后再更新 相当于只是执行最后一组指令