题意翻译
有一个r行c列(1≤r,c≤50)的电子表格,行从上到下编号为1~r,列从左到右编号为 1~c。如图(a)所示,如果先删除第1、5行,然后删除第3,6,7,9列,结果如图©所示。
接下来在第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。
输入样例
输入
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)
A | B | C | D | E | F | G | H | I | |
---|---|---|---|---|---|---|---|---|---|
1 | 22 | 55 | 66 | 77 | 88 | 99 | 10 | 12 | 14 |
2 | 2 | 24 | 6 | 8 | 22 | 12 | 14 | 16 | 18 |
3 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
4 | 24 | 25 | 26 | 67 | 22 | 69 | 70 | 71 | 77 |
5 | 68 | 78 | 79 | 80 | 22 | 25 | 28 | 29 | 30 |
6 | 16 | 12 | 11 | 10 | 22 | 56 | 57 | 58 | 59 |
7 | 33 | 34 | 35 | 36 | 22 | 38 | 39 | 40 | 41 |
A | B | C | D | E | |
---|---|---|---|---|---|
1 | 2 | 24 | 8 | 22 | 16 |
2 | 18 | 19 | 21 | 22 | 25 |
3 | 24 | 25 | 67 | 22 | 71 |
4 | 16 | 12 | 10 | 22 | 78 |
5 | 33 | 34 | 36 | 22 | 40 |
A | B | C | D | E | F | |
---|---|---|---|---|---|---|
1 | 2 | 24 | 8 | 22 | 16 | |
2 | ||||||
3 | 18 | 19 | 21 | 22 | 25 | |
4 | ||||||
5 | 24 | 25 | 67 | 22 | 71 | |
6 | 16 | 12 | 10 | 22 | 58 | |
7 | ||||||
8 | 33 | 34 | 36 | 22 | 40 |
#define _CRT_SECURE_NO_WARNINGS
#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);
void del(char type);
void ins(char type);
int main()
{
int r1, r2, c1, c2, q, kase = 0;
char cmd[10]; //存放 DC DR 等命令
memset(d, 0, sizeof(d));
while (scanf("%d%d", &r, &c) == 2 && r && scanf("%d", &n) == 1) { //r=c=n=0时结束
int r0 = r, c0 = c;
for (int i = 1; i <= r; i++) {
for (int j = 1; j <= c; j++) {
d[i][j] = i * BIG + j;
/*
* d[i][j] % BIG = j, d[i][j] / BIG = i
* d[i][j]存放(i,j)的最初位置
*/
}
}
while (n--) {//处理n个操作
scanf("%s", cmd);
if (cmd[0] == 'E') { //交换
scanf("%d%d%d%d", &r1, &c1, &r2, &c2);
int t = d[r1][c1];
d[r1][c1] = d[r2][c2]; //(r1,c1)最初的位置在(r2,c2)
d[r2][c2] = t;
}
else { //插入删除操作
int a, x;
scanf("%d", &a);
//cols记录删除或插入的行列,cols[i]=1表示i/列需要进行操作
memset(cols, 0, sizeof(cols));
for (int i = 0; i < a; i++) { scanf("%d", &x); cols[x] = 1; }
if (cmd[0] == 'D') del(cmd[1]);//del操作,参数为'R'/'C'
else ins(cmd[1]);
}
}
memset(ans, 0, sizeof(ans));
for (int i = 1; i <= r; i++) {
for (int j = 1; j <= c; j++) {
ans[d[i][j] / BIG][d[i][j] % BIG] = i * BIG + j;
//ans[][]表示(d[i][j] / BIG,d[i][j] % BIG)移动后的位置为(i,j)
//相当于把ans存放的是移动后的位置
}
}
if (kase > 0) printf("\n");//kase表示第几次输入
printf("Spreadsheet #%d\n", ++kase);
scanf("%d", &q);//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;
}
void copy(char type, int p, int q) //根据type 将d2第q的行/列 copy到d的第p行/列
{
if (type == 'R') {
for (int j = 1; j <= c; j++) {
d[p][j] = d2[q][j];
}
}
else {
for (int i = 1; i <= r; i++) {
d[i][p] = d2[i][q];
}
}
}
void del(char type) //del操作
{
memcpy(d2, d, sizeof(d));//d2相当于临时的副本
int cnt = (type == 'R') ? r : c;
int cnt2 = 0;
for (int i = 1; i <= cnt; i++) {
if (!cols[i]) copy(type, ++cnt2, i);
//如果cols[i]==0,表示该行/列不删除,复制到d中,否则被删掉
}
//更换r,c范围
if (type == 'R') r = cnt2;
else c = cnt2;
}
void ins(char type) //insert操作,与del操作同理
{
memcpy(d2, d, sizeof(d));
int cnt = (type == 'R') ? r : c;
int cnt2 = 0;
for (int i = 1; i <= cnt; i++) {
if (cols[i]) copy(type, ++cnt2, 0); //i行/列前插入一行 全置0
copy(type, ++cnt2, i);//将i行/列copy过去
}
if (type == 'R') r = cnt2;
else c = cnt2;
}