追踪电子表格中的单元格 (Spreadsheet Tracking)

题意翻译
有一个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)
ABCDEFGHI
1225566778899101214
2224682212141618
3181920212223242526
4242526672269707177
5687879802225282930
6161211102256575859
73334353622383940 

41

(b)
ABCDE
122482216
21819212225
32425672271
41612102278
53334362240

(c)
ABCDEF
122482216
2
31819212225
4
52425672271
61612102258
7
83334362240

#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;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值