第三十二题 UVA512 追踪电子表格中的单元格 Spreadsheet Tracking

PDF

题意翻译
有一个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。

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

感谢@BFD_qt 提供翻译

输入输出样例
输入 #1复制
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
输出 #1复制
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)

思路:
两种思路!!!! 一是比较好想的,直接根据操作,按照要求修改表格,最后查询即可。 二是 保存下每次修改操作 ,对于每次询问,重新遍历所有的修改,得出答案。第二种思路更好,效率也更高,但是比较难写。

下面是第一种思路的代码,参考紫书上刘老师的代码,刘老师的巧妙之处在于d2数组的巧妙利用,对于每次修改不是修改,而是重新“做”一张表,“做”的这张表就参考d2数组

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define Maxn 52
#define GI 10000
using namespace std;
int d[Maxn][Maxn],d2[Maxn][Maxn],ans[Maxn][Maxn];
int r,c,n,q,cols[Maxn];

inline void Copy(char typ,int p,int q) {
	if(typ == 'R') {
		for(int i=1; i<=c; i++)
			d[p][i] = d2[q][i];
	}
	else {
		for(int i=1; i<=r; i++)
			d[i][p] = d2[i][q];
	}
}

inline void Ins(char typ) {
	memcpy(d2,d,sizeof(d));
	int cnt = typ == 'R' ? r : c,cnt2 = 0;
	for(int i=1; i<=cnt; i++) {
		if(cols[i]) Copy(typ,++cnt2,0);// 第i行前 插入一行 
		Copy(typ,++cnt2,i);
	}
	if(typ == 'R') r = cnt2;
	else c = cnt2;
} 

inline void Del(char typ) {
	memcpy(d2,d,sizeof(d));
	int cnt = typ == 'R' ? r : c,cnt2 = 0;
	for(int i=1; i<=cnt; i++) {
		if(!cols[i]) Copy(typ,++cnt2,i);// 没删除的 复制过来 
	}
	if(typ == 'R') r = cnt2;
	else c = cnt2;
}

int main(int argc,char* argv[]) {
	int kase = 0,r1,c1,r2,c2,a,x;
	char cmd[10];
	memset(d,0,sizeof(d));
	while(scanf("%d %d %d",&r,&c,&n) == 3 && r) {
		for(int i=1; i<=r; i++)
			for(int j=1; j<=c; j++)
				d[i][j] = i * GI + j;
		while(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]; d[r2][c2] = t;
			}
			else {
				scanf("%d",&a); memset(cols,0,sizeof(cols));
				//cols[i]=1电表第i行或者列 需要删除或者增添
				for(int i=1; i<=a; i++) { scanf("%d",&x); cols[x] = 1; }
				if(cmd[0] == 'D') Del(cmd[1]);
				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] / GI][d[i][j] % GI] = i * GI + j;
		if(kase > 0) printf("\n");
		printf("Spreadsheet #%d\n", ++kase);
		scanf("%d",&a);
		while(a--) {
			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] / GI, ans[r1][c1] % GI);
		}           		
	}
	return 0;
}
发布了732 篇原创文章 · 获赞 31 · 访问量 17万+

猜你喜欢

转载自blog.csdn.net/qq_35776409/article/details/103945011