追踪电子表格中的单元格

 

话不多说直接,上代码,有注释,这题做到吐,一定要最后输出的格式,看了一个小时没看出来错,结果是最后多输出一个单词,淦

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define maxn 100
#define BIG 100000

int a[maxn][maxn];//保存最后得到的表格
int b[maxn][maxn];//b数组作为媒介去交换去删除或添加某一行
int c[maxn][maxn];//将最后得到的表格按照原来的行列防在数组中
int d[maxn];//用于记录要删除或者增加的行或列
int row, colum;

//遇到错误是用于输出当前数组是什么样子的,亲测好用!
void show(int a[100][100])
{
    for (int i = 1; i <= 7; i++)
    {
        for (int j = 1; j <= 9; j++)
        {
            printf("%7d ", a[i][j]);
        }
        printf("\n");
    }
    printf("\n");
}

//用于每次增加或者删减列或行的函数,四个命令都可以解决
void copy(char type,int p,int q)
{
    if (type == 'R')
    {
        for (int i = 1; i <= colum; i++)
            a[p][i] = b[q][i];
    }
    else
    {
        for (int i = 1; i <= row; i++)
            a[i][p] = b[i][q];
    }
}

void del(char type)
{
    memcpy(b, a, sizeof(a));
    int cnt = type == 'R' ? row:colum;
    int cnt2 = 0;
    for (int i = 1; i <= cnt; i++)
    {
        if (!d[i])copy(type, ++cnt2, i); //其实相当于cnt2和i分别指向a数组和b数组,如果该行需要删除,那么直接跳过该行,cnt2不增加,但是i继续增加,当遇到不需要删除的行时,直接用当前i行去覆盖需要删除的cnt2行
    }
    if (type == 'R')row = cnt2;//最后的cnt2就是执行完操作之后的总列数或者总行数
    else colum = cnt2;
}

void ins(char type)
{
    memcpy(b, a, sizeof(a));
    int cnt = type == 'R' ? row : colum;
    int cnt2 = 0;
    for (int i = 1; i <= cnt; i++)
    {
        if (d[i])copy(type, ++cnt2, 0);//相当于cnt2和i分别指向a数组和b数组,如果遇到需要插入的行,那么直接将该行用0覆盖
        copy(type, ++cnt2, i);//假如cnt2行被覆盖后,马上将原数组被覆盖的那一行的原数据传入cnt2+1的那一行,往后每次都会覆盖。
    }
    if (type == 'R')row = cnt2;
    else colum = cnt2;
}

int main(void)
{
    int kcase = 0;
    int r1, c1, r2, c2;
    char com[10];
    while (scanf("%d %d", &row, &colum) == 2&&row)
    {
        memset(a, 0, sizeof(a));
        for (int i = 1; i <= row; i++)
        {
            for (int j = 1; j <= colum; j++)
            {
                a[i][j] = BIG * i + j;//用于记录初始数组的行和列
            }
        }
        int n;//要执行的总命令次数
        scanf("%d", &n);
        for (int i = 0; i < n; i++)
        {
            //每一子个命令执行的次数
            scanf("%s", com);
            if (com[0] == 'E')
            {
                scanf("%d %d %d %d", &r1, &c1, &r2, &c2);
                int t = a[r1][c1];
                a[r1][c1] = a[r2][c2];
                a[r2][c2] = t;
            }
            else
            {
                int num;
                scanf("%d", &num);
                memset(d, 0, sizeof(d));
                for (int j = 0; j < num; j++)
                {
                    int p;
                    scanf("%d", &p);
                    d[p] = 1;//确定某一行或列是否需要插入或删除
                }

                //判断是插入还是删除
                if (com[0] == 'D')
                {
                    del(com[1]);
                }
                else
                {
                    ins(com[1]);
                }
            }
        }

        memset(c, 0, sizeof(c));
        //将最终的a数组按照原来的列数和行数放在c数组中,就知道哪些地方是GONE
        for (int i = 1; i <= row; i++)
        {
            for (int j = 1; j <= colum; j++)
            {
                c[a[i][j] / BIG][a[i][j] % BIG] = BIG * i + j;//将数据放在原来的位置,并且记录上现在他们所在的位置
            }
        }
        if (kcase > 0) printf("\n");
        printf("Spreadsheet #%d\n", ++kcase);
        
        int count;//查询次数
        scanf("%d", &count);
        for (int i = 0; i < count; i++)
        {
            int x, y;
            scanf("%d %d", &x, &y);
            printf("Cell data in (%d,%d) ", x, y);
            if (c[x][y] == 0)printf("GONE\n");
            else printf("moved to (%d,%d)\n", c[x][y] / BIG, c[x][y] % BIG);
        }
    }
    return 0;
}

 

posted @ 2021-01-27 19:54  loliconsk  阅读(143)  评论(0)    收藏  举报