UVa - 512 Spreadsheet Tracking
思路1:首先模拟操作,算出最后的电子表格,然后在每次查询时直接在电子表格中找到所求的单元格。
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 100,big = 10000;
char cmd[10];
int r,c,n,rc_num,qu_num,r1,c1,r2,c2,kcase = 0;
int d[maxn][maxn],d2[maxn][maxn],ans[maxn][maxn],cols[maxn];
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 cmd){
memcpy(d2,d,sizeof(d));
int cnt = cmd == 'R' ? r : c,cnt2 = 0;
for(int i = 1;i <= cnt;i++){
if(!cols[i]) copy(cmd,++cnt2,i);
}
(cmd == 'R' ? r : c) = cnt2;
}
void ins(char cmd){
memcpy(d2,d,sizeof(d));
int cnt = cmd == 'R' ? r : c,cnt2 = 0;
for(int i = 1;i <= cnt;i++){
if(cols[i]) copy(cmd,++cnt2,0);
copy(cmd,++cnt2,i);
// ++cnt2;
// if(!cols[i]) copy(cmd,cnt2,i);这样不对
}
(cmd == 'R' ? r : c) = cnt2;
}
int main(){
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*big + 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",&rc_num);
memset(cols,0,sizeof(cols));
int t = 0;
while(rc_num--){
scanf("%d",&t);
cols[t] = 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 > 1) putchar('\n');
printf("Spreadsheet #%d\n",kcase);
scanf("%d",&qu_num);
while(qu_num--){
scanf("%d%d",&r1,&c1);
printf("Cell data in (%d,%d) ",r1,c1);
if(!ans[r1][c1]) printf("GONE\n");
else printf("moved to (%d,%d)\n",ans[r1][c1] / big,ans[r1][c1] % big);
}
}
return 0;
}
思路二:将所有操作保存,然后对于每个查询重新执行每个操作,但不需要计算整个电子表格的变化,而只需关注所查询的单元格的位置变化。对于题目给定的规模来说,这个方法不仅更好写,而且效率更高。
#include<cstdio>
#include<cstring>
using namespace std;
const int maxd = 10000;
int r,c,n;
struct comand{
char c[5];
int r1,c1,r2,c2;
int a,x[100];
}cmd[maxd];
int simulate(int* qr,int *qc){
for(int i = 0;i < n;i++){
if(cmd[i].c[0] == 'E'){
if(*qr == cmd[i].r1 && *qc == cmd[i].c1){
*qr = cmd[i].r2;
*qc = cmd[i].c2;
}else if(*qr == cmd[i].r2 && *qc == cmd[i].c2){
*qr = cmd[i].r1;
*qc = cmd[i].c1;
}
}else{
int dr = 0,dc = 0;
if(cmd[i].c[0] == 'D'){
for(int j = 0;j < cmd[i].a;j++){
int x = cmd[i].x[j];
if(cmd[i].c[1] == 'R'){
if(*qr == x) return 0;
if(*qr > x) dr--;
}else{
if(*qc == x) return 0;
if(*qc > x) dc--;
}
}
}else{
for(int j = 0;j < cmd[i].a;j++){
int x = cmd[i].x[j];
if(cmd[i].c[1] == 'R' && *qr >= x) dr++;
if(cmd[i].c[1] == 'C' && *qc >= x) dc++;
}
}
*qr += dr;
*qc += dc;
}
}
return 1;
}
int main(){
int qu_num,r1,c1,kcase = 0;
while(scanf("%d%d%d",&r,&c,&n) == 3 && r){
for(int i = 0;i < n;i++){
scanf("%s",cmd[i].c);
if(cmd[i].c[0] == 'E') scanf("%d%d%d%d",&cmd[i].r1,&cmd[i].c1,&cmd[i].r2,&cmd[i].c2);
else{
scanf("%d",&cmd[i].a);
for(int j = 0;j < cmd[i].a;j++)
scanf("%d",&cmd[i].x[j]);
}
}
if(++kcase > 1) putchar('\n');
printf("Spreadsheet #%d\n",kcase);
scanf("%d",&qu_num);
while(qu_num--){
scanf("%d%d",&r1,&c1);
printf("Cell data in (%d,%d) ",r1,c1);
if(!simulate(&r1,&c1)) printf("GONE\n");
else printf("moved to (%d,%d)\n",r1,c1);
}
}
return 0;
}