例题4-5 UVA512追踪电子表格中的单元格

思路一:首先进行模拟操作,算出最后的整个电子表格,然后每次查询时直接在电子表格中找到所求的单元格。

d[i][j]表示变化后的电子表格中坐标为i,j的单元格所存储的原来表格中的单元格坐标信息。

ans[i][j]表示原来坐标为i,j的单元格现在的位置。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxh 50000
using namespace std;
int i,j,r,c,r1,c1,r2,c2,orr,orc,tim,t1,options,num,testnum,target;
char op[3];int d[51][51];int d2[51][51];int mark[51];int ans[51][51];
void copyi(char s,int p,int q);
void exchange(int r1,int c1,int r2,int c2);
void del(char s);
void ins(char s);
int main()
{
    tim=1;
    while((cin>>r>>c)&&r)
    {
        if(tim>1)
        {
            cout<<endl;
        }
        cout<<"Spreadsheet #"<<tim<<endl;tim++;
        memset(d,0,sizeof(d));
        memset(d2,0,sizeof(d2));
        for(i=1;i<=r;i++)
            for(j=1;j<=c;j++)
        {
            d[i][j]=i*maxh+j;
        }
        cin>>options;
        while(options--)
        {
            cin>>op;
            if(op[0]=='E')
            {
                cin>>r1>>c1>>r2>>c2;
                exchange(r1,c1,r2,c2);
            }
            else if(op[0]=='D')
            {
                cin>>num;
                memset(mark,0,sizeof(mark));
                while(num--)
                {
                    cin>>target;
                    mark[target]=1;
                }
                del(op[1]);
            }
            else if(op[0]=='I')
            {
                cin>>num;
                memset(mark,0,sizeof(mark));
                while(num--)
                {
                    cin>>target;
                    mark[target]=1;
                }
                ins(op[1]);
            }
        }
        memset(ans,0,sizeof(ans));
        for(i=1;i<=r;i++)
            for(j=1;j<=c;j++)
        {
            ans[d[i][j]/maxh][d[i][j]%maxh]=i*maxh+j;
        }
        cin>>testnum;
        while(testnum--)
        {
            cin>>orr>>orc;
            cout<<"Cell data in ("<<orr<<","<<orc<<") ";
            if(ans[orr][orc]==0)
            {
                cout<<"GONE"<<endl;
            }
            else
            {
                cout<<"moved to ("<<(ans[orr][orc]/maxh)<<","<<(ans[orr][orc]%maxh)<<")"<<endl;
            }
        }

    }
}
void copyi(char s,int p,int q)
{
    if(s=='R')
    {
        for(int k=1;k<=c;k++)
        {
            d[p][k]=d2[q][k];
        }
    }
    else
    {
        for(int k=1;k<=r;k++)
        {
            d[k][p]=d2[k][q];
        }
    }
}
void exchange(int r1,int c1,int r2,int c2)
{
    t1=d[r1][c1];
    d[r1][c1]=d[r2][c2];
    d[r2][c2]=t1;
}
void del(char s)
{
    memcpy(d2,d,sizeof(d));
    int cnt=s=='R'?r:c,cnt2=0;
    for(i=1;i<=cnt;i++)
    {
        if(!mark[i])
        {
            copyi(s,++cnt2,i);
        }
    }
    if(s=='R')
    {
        r=cnt2;
    }
    else
    {
        c=cnt2;
    }
}
void ins(char s)
{
    memcpy(d2,d,sizeof(d));
    int cnt=s=='R'?r:c,cnt2=0;
    for(int i=1;i<=cnt;i++)
    {
        if(mark[i])
        {
            copyi(s,++cnt2,0);
        }
        copyi(s,++cnt2,i);
    }
    if(s=='R')
    {
        r=cnt2;
    }
    else
    {
        c=cnt2;
    }
}

思路二:将所有的操作保存,然后对于每一个查询重新执行每个操作,不需要计算整个电子表格的变化,只需要关注所查询的单元格的位置变化。此方法更为简便,效率高。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxh 50000
using namespace std;
int r,c,orr,orc,tim,options,testnum;
struct Command{
    char ch[5];
    int r1,c1,r2,c2;
    int a,x[20];
}cmd[maxh];
int simulate();
int main()
{
    tim=1;
    while((cin>>r>>c)&&r)
    {
        if(tim>1)
        {
            cout<<endl;
        }
        cout<<"Spreadsheet #"<<tim<<endl;tim++;
        cin>>options;
        for(int i=0;i<options;i++)
        {
            cin>>cmd[i].ch;
            if(cmd[i].ch[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];
                }
            }
        }
        cin>>testnum;
        while(testnum--)
        {
            cin>>orr>>orc;
            cout<<"Cell data in ("<<orr<<","<<orc<<") ";
            if(!simulate())
            {
                cout<<"GONE"<<endl;
            }
            else
            {
                cout<<"moved to ("<<orr<<","<<orc<<")"<<endl;
            }
        }

    }
}
int simulate()
{
    for(int i=0;i<options;i++)//每一条指令执行后,需要更新坐标值
    {
        if(cmd[i].ch[0]=='E')
        {
            if(cmd[i].r1==orr&&cmd[i].c1==orc)
            {
                orr=cmd[i].r2;orc=cmd[i].c2;
            }
            else if(cmd[i].r2==orr&&cmd[i].c2==orc)
            {
                orr=cmd[i].r1;orc=cmd[i].c1;
            }
        }
        else
        {
            int dr=0,dc=0;//每一条指令 删除/增添若干行/列,行与行,列与列变化是同时进行的,所以需要先保持orr,orc不发生变化,然后操作完成一步后再进行运算
            for(int j=0;j<cmd[i].a;j++)
            {
                int k=cmd[i].x[j];
                if(cmd[i].ch[0]=='D')
                {
                    if((cmd[i].ch[1]=='R'&&k==orr)||(cmd[i].ch[1]=='C'&&k==orc))
                    {
                        return 0;
                    }
                    if(cmd[i].ch[1]=='R'&&k<orr)
                    {
                        dr--;
                    }
                    if(cmd[i].ch[1]=='C'&&k<orc)
                    {
                        dc--;
                    }
                }
                else//插入空行
                {
                    if(cmd[i].ch[1]=='R'&&k<=orr)
                    {
                        dr++;
                    }
                    if(cmd[i].ch[1]=='C'&&k<=orc)
                    {
                        dc++;
                    }
                }
            }
            orr+=dr;orc+=dc;
        }
    }
    return 1;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值