512:Spreadsheet Tracking

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

posted @ 2018-04-11 20:42  ACLJW  阅读(175)  评论(0编辑  收藏  举报