题目大意:
有一个r×c的表格,对它执行一系列操作,再查询之前的单元格变换后的状态。每次执行n个操作,操作有5种:EX是交换操作,后给出r1,c1,r2,c2两个需要交换的单元格;D是删除操作,I是插入操作,后面的C/R分别是对列和对行的操作,A是操作的行/列数,后面A个xi是具体的行/列。一共有q次查询,每次查询都给出原单元格的位置r,c。多组输入,输入0 0结束。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#define maxn 1000
using namespace std;
struct node
{
char c[5];
int r1,c1,r2,c2;
int a;
int x[maxn];
} cmd[maxn];
int main()
{
int r,n,c,q;
int kase = 1;
while(cin >> r >> c >> n && r)
{
for(int i=0; i<n; i++)
{
cin >> cmd[i].c;
if(cmd[i].c[0] == 'E')
{
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(kase > 1) cout << endl;
cout << "Spreadsheet #" << kase++ << endl;
cin >> q;
int r0,c0;
while(q--)
{
cin >> r0 >> c0;
int flag = 1;
printf("Cell data in (%d,%d) ",r0,c0);
for(int i=0; i<n; i++)
{
int dr=0, dc=0;
if(cmd[i].c[0] == 'E')
{
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 if(cmd[i].c[0] == 'D')
{
for(int j=0; j<cmd[i].a; j++)
{
if((cmd[i].c[1] == 'C' && cmd[i].x[j] == c0) || (cmd[i].c[1] == 'R' && cmd[i].x[j] == r0))
{
flag = 0;
}
else if(cmd[i].c[1] == 'C' && cmd[i].x[j] < c0)
{
dc--;
}
else if(cmd[i].c[1] == 'R' && cmd[i].x[j] < r0)
{
dr--;
}
}
r0 += dr;
c0 += dc;
}
else if(cmd[i].c[0] == 'I')
{
for(int j=0; j<cmd[i].a; j++)
{
if(cmd[i].c[1] == 'C' && cmd[i].x[j] <= c0)
{
dc++;
}
if(cmd[i].c[1] == 'R' && cmd[i].x[j] <= r0)
{
dr++;
}
}
r0 += dr;
c0 += dc;
}
}
if(flag)
printf("moved to (%d,%d)\n",r0,c0);
else
printf("GONE\n");
}
}
return 0;
}
反思:
二维数组模拟表格,一种思路是操作完后再查询,另一种是保存操作,每次查询再执行操作,只关注所需查询的单元格的位置变化。这里用第二种思路,不用改变整个表格,也便于理解。用一个结构体保存操作command、A、x[A]、r1、c1、r2、c2。dc和dr分别记录c0和r0改变的行列数。