根据紫书做的,非常佩服作者的思路,我只改了一点点内容
第一段代码的思路是直接模拟操作,算出最后的电子表格,然后在最后的查询操作根据电子表格找出对应的单元格
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
#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) {
if (type == '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];
}
void del(char type) {
memcpy(d2, d, sizeof(d));
int cnt = type == 'R' ? r : c, cnt2 = 0;
for (int i = 1; i <= cnt; i++)
if (!cols[i])
copy(type, ++cnt2, i);
if (type == 'R')
r = cnt2;
else
c = cnt2;
}
void ins(char type) {
memcpy(d2, d, sizeof(d));
int cnt = type == 'R' ? r : c, cnt2 = 0;
for (int i = 1; i <= cnt; i++) {
if (cols[i])
copy(type, ++cnt2, 0);
copy(type, ++cnt2, i);
}
if (type == 'R')
r = cnt2;
else
c = cnt2;
}
int main() {
int r1, c1, r2, c2, q, kcase = 0;
string cmd;
memset(d, 0, sizeof(d));
while ((cin >> r >> c).good() && r) {
cin >> n;
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;
while (n--) {
cin >> cmd;
if (cmd == "EX") {
cin >> r1 >> c1 >> r2 >> c2;
int temp = d[r1][c1];
d[r1][c1] = d[r2][c2];
d[r2][c2] = temp;
}
else {
int a, x;
cin >> a;
memset(cols, 0, sizeof(cols));
for (int i = 0; i < a; i++) {
cin >> 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]/BIG][d[i][j]%BIG] = i*BIG + j;
if (kcase > 0)
putchar('\n');
printf("Spreadsheet #%d\n", ++kcase);
cin >> q;
while (q--) {
cin >> r1 >> c1;
printf("Cell data in (%d,%d) ", r1, c1);
if (ans[r1][c1] == 0)
puts("GONE");
else
printf("moved to (%d,%d)\n", ans[r1][c1]/BIG, ans[r1][c1]%BIG);
}
}
return 0;
}
第二段代码就是将所有操作保存起来,然后对于每个查询的表格执行对应的操作,觉得这种做法更加简洁,而且效率也更高
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
#define maxd 10000
struct Command {
string c;
int r1, c1, r2, c2;
int a, x[20];
} cmd[maxd];
int r, c, n;
int simulate(int & r0, int & c0) {
for (int i = 0; i < n; i++) {
if (cmd[i].c == "EX") {
if (cmd[i].r1 == r0 && cmd[i].c1 == c0) {
r0 = cmd[i].r2;
c0 = cmd[i].c2;
}
else if (cmd[i].r2 == r0 && cmd[i].c2 == c0) {
r0 = cmd[i].r1;
c0 = cmd[i].c1;
}
}
else {
int dr = 0, dc = 0;
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++;
}
else {
if (cmd[i].c[1] == 'R' && x == r0)
return 0;
if (cmd[i].c[1] == 'C' && x == c0)
return 0;
if (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() {
int r0, c0, q, kcase = 0;
while ((cin >> r >> c).good() && r) {
cin >> n;
for (int i = 0; i < n; i++) {
cin >> cmd[i].c;
if (cmd[i].c == "EX") {
cin >> cmd[i].r1 >> cmd[i].c1 >> cmd[i].r2 >> cmd[i].c2;
}
else {
cin >> cmd[i].a;
for (int j = 0; j < cmd[i].a; j++)
cin >> cmd[i].x[j];
}
}
if (kcase > 0)
putchar('\n');
printf("Spreadsheet #%d\n", ++kcase);
cin >> q;
while (q--) {
cin >> r0 >> c0;
printf("Cell data in (%d,%d) ", r0, c0);
if (!simulate(r0, c0))
printf("GONE\n");
else
printf("moved to (%d,%d)\n", r0, c0);
}
}
return 0;
}