UVALive5198 UVA512 Spreadsheet Tracking【模拟】

281 篇文章 4 订阅
96 篇文章 5 订阅

 Data in spreadsheets are stored in cells, which are organized in rows (r) and columns (c). Some operations on spreadsheets can be applied to single cells (r, c), while others can be applied to entire rows or columns. Typical cell operations include inserting and deleting rows or columns and exchanging cell contents.

 Some spreadsheets allow users to mark collections of rows or columns for deletion, so the entire collection can be deleted at once. Some (unusual) spreadsheets allow users to mark collections of rows or columns for insertions too. Issuing an insertion command results in new rows or columns being inserted before each of the marked rows or columns. Suppose, for example, the user marks rows 1 and 5 of the spreadsheet on the left for deletion. The spreadsheet then shrinks to the one on the right.


 If the user subsequently marks columns 3, 6, 7, and 9 for deletion, the spreadsheet shrinks to this.


If the user marks rows 2, 3 and 5 for insertion, the spreadsheet grows to the one on the left. If the user then marks column 3 for insertion, the spreadsheet grows to the one in the middle. Finally, if the user exchanges the contents of cell (1,2) and cell (6,5), the spreadsheet looks like the one on the right.


 You must write tracking software that determines the final location of data in spreadsheets that result from row, column, and exchange operations similar to the ones illustrated here.

Input

 The input consists of a sequence of spreadsheets, operations on those spreadsheets, and queries about them. Each spreadsheet definition begins with a pair of integers specifying its initial number of rows(r) and columns (c), followed by an integer specifying the number (n) of spreadsheet operations. Row and column labeling begins with 1. The maximum number of rows or columns of each spreadsheet is limited to 50. The following n lines specify the desired operations.

 An operation to exchange the contents of cell (r1, c1) with the contents of cell (r2, c2) is given by:

    EX r1 c1 r2 c2

 The four insert and delete commands—DC (delete columns), DR (delete rows), IC (insert columns), and IR (insert rows) are given by:

    < command > A x1 x2 . . . xA

where < command > is one of the four commands; A is a positive integer less than 10, and x1, . . . , xA are the labels of the columns or rows to be deleted or inserted before. For each insert and delete command, the order of the rows or columns in the command has no significance. Within a single delete or insert command, labels will be unique.

  The operations are followed by an integer which is the number of queries for the spreadsheet. Each query consists of positive integers r and c, representing the row and column number of a cell in the original spreadsheet. For each query, your program must determine the current location of the data that was originally in cell (r, c). The end of input is indicated by a row consisting of a pair of zeros for the spreadsheet dimensions.

Output

 For each spreadsheet, your program must output its sequence number (starting at 1). For each query, your program must output the original cell location followed by the final location of the data or the word ‘GONE’ if the contents of the original cell location were destroyed as a result of the operations. Separate output from different spreadsheets with a blank line.

 The data file will not contain a sequence of commands that will cause the spreadsheet to exceed the maximum size.

Sample Input

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

Sample Output

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)


问题链接UVALive5198 UVA512 Spreadsheet Tracking

问题简述

 这是一个电子表格操作的模拟题。先输入电子表格总的行和列的正整数r和c,满足r,c<=50,r和c均为0时,输入测试实例结束;然后输入命令数n,跟着是n条命令,包括:

 1. EX r1 c1 r2 c2,其含义是两个单元交换,即<r1,c1>和<r2,c2>内容交换;

 2. 插入和删除命令,共4条,分别是DC(删除列)、DR(删除行)、IC(插入列)和IR(插入行),其格式如下:

    < command > A x1 x2 . . . xA

其中,A为正整数,值小于10,指定其后列表xi的元素个数;列表x为删除或插入的行或列(是行还是列由命令决定)。

  然后输入一个单元数,其后跟着若干个单元(r,c),r和c分别是单元的行和列坐标。对于每一个单元坐标,计算输出执行上面的命令序列之后,左边变为多少?

问题分析

  采用先读入命令序列,再进行重复模拟的工作方式,相对而言比较易于理解和实现。

程序说明

  结构数组cmd[]用于存储电子表格命令,枚举语句(enum operation {EX, DC, DR, IC, IR};)用于将命令转换为整数形式,函数simulate()用于模拟命令的执行。


AC的C语言程序如下:

/* UVALive5198 UVA512 Spreadsheet Tracking */

#include <stdio.h>
#include <stdlib.h>

#define MAXN 50
#define MAXN2 10
#define MAXN3 10000

int grid[MAXN+1][MAXN+1];

enum operation {EX, DC, DR, IC, IR};
struct {
    int cmd;
    int a, x[MAXN2+1];
} cmd[MAXN3];
int ccount;

int cmp(const void *a,const void *b)
{
    return *(int*)a - *(int*)b;
}

void getax(int index)
{
    int i;

    scanf("%d", &cmd[index].a);
    for(i=0; i<cmd[index].a; i++)
        scanf("%d", &cmd[index].x[i]);

    qsort(cmd[index].x, cmd[index].a, sizeof(cmd[index].x[0]), cmp);
}

void simulate(int row, int col)
{
    int row1, col1, row2, col2, i, j;

    row1 = row2 = row;
    col1 = col2 = col;

    for(i=0; i<ccount; i++) {
        switch(cmd[i].cmd) {
        case EX:
            if(row2 == cmd[i].x[0] && col2 == cmd[i].x[1]) {
                row1 = row2 = cmd[i].x[2];
                col1 = col2 = cmd[i].x[3];
            } else if(row2 == cmd[i].x[2] && col2 == cmd[i].x[3]) {
                row1 = row2 = cmd[i].x[0];
                col1 = col2 = cmd[i].x[1];
            }
            break;
        case DR:
            for(j=0; j<cmd[i].a; j++) {
                if(cmd[i].x[j] == row1) {
                    printf("Cell data in (%d,%d) GONE\n", row, col);
                    return;
                } else if(cmd[i].x[j] < row1) {
                    row2--;
                } else
                    break;
            }
            row1 = row2;
            break;
        case DC:
            for(j=0; j<cmd[i].a; j++) {
                if(cmd[i].x[j] == col1) {
                    printf("Cell data in (%d,%d) GONE\n", row, col);
                    return;
                } else if(cmd[i].x[j] < col1) {
                    col2--;
                } else
                    break;
            }
            col1 = col2;
            break;
        case IR:
            for(j=0; j<cmd[i].a; j++) {
                if(cmd[i].x[j] <= row1) {
                    row2++;
                } else
                    break;
            }
            row1 = row2;
            break;
        case IC:
            for(j=0; j<cmd[i].a; j++) {
                if(cmd[i].x[j] <= col1) {
                    col2++;
                } else
                    break;
            }
            col1 = col2;
            break;
        }
    }

    printf("Cell data in (%d,%d) moved to (%d,%d)\n", row, col, row2, col2);
}

int main(void)
{
    int caseno, r, c, n, i;
    char command[8];
    int cn, row, col;

    caseno = 0;
    while(scanf("%d%d", &r, &c) != EOF) {
        if(r == 0 && c == 0)
            break;

        /* 读入命令,存储在结构数组cmd[]中 */
        ccount = 0;
        scanf("%d", &n);
        for(i=1; i<=n; i++) {
            scanf("%s", command);

            if(command[0] == 'E') {
                /* 单元内容交换命令 */
                cmd[ccount].cmd = EX;
                scanf("%d%d%d%d", &cmd[ccount].x[0], &cmd[ccount].x[1], &cmd[ccount].x[2], &cmd[ccount].x[3]);
                ccount++;
            } else if(command[0] == 'D') {
                cmd[ccount].cmd = (command[1] == 'C') ? DC : DR;
                getax(ccount);
                ccount++;
            } else if(command[0] == 'I') {
                cmd[ccount].cmd = (command[1] == 'C') ? IC : IR;
                getax(ccount);
                ccount++;
            }
        }

        if(caseno)
            printf("\n");
        printf("Spreadsheet #%d\n", ++caseno);

        /* 读入单元坐标进行模拟 */
        scanf("%d", &cn);
        for(i=1; i<=cn; i++) {
            scanf("%d%d", &row, &col);
            simulate(row, col);
        }
    }

    return 0;
}


 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值