uva 512

这是一道字符串处理的题目。但通过自己写的和书上写的代码对比,也是学到一些东西。
我一开始想存储一个点变换后的坐标需要两个值(x,y),再加上一个bool类型的变量判断这个点有没有被删去即可。因此写出代码如下:

#include<stdio.h>
#include<string.h>
#define maxn 55

struct point{
    int ansx;
    int ansy;
    bool exist;
};
point pt[maxn][maxn];

int r,c,n;

void DC(int x){
    for(int i = 1;i<=r;i++){
        for(int j=1;j<=c;j++){
            if(pt[i][j].ansy==x) pt[i][j].exist = false;
            else if(pt[i][j].ansy>x) pt[i][j].ansy--;
            else{}
        }
    }
} 

void DR(int x){
    for(int i = 1;i<=r;i++){
        for(int j=1;j<=c;j++){
            if(pt[i][j].ansx==x) pt[i][j].exist = false;
            else if(pt[i][j].ansx>x) pt[i][j].ansx--;
            else{}
        }
    }
}

void IC(int x){
    for(int i = 1;i<=r;i++){
        for(int j=1;j<=c;j++){
            if(pt[i][j].ansy>=x) pt[i][j].ansy++ ;
        }
    }
}

void IR(int x){
    for(int i = 1;i<=r;i++){
        for(int j=1;j<=c;j++){
            if(pt[i][j].ansx>=x) pt[i][j].ansx++ ;
        }
    }
}

int main(){
    int i,j,r1,r2,c1,c2,q,kase=0;
    char cmd[15];
    while(scanf("%d%d%d",&r,&c,&n)&&r){
        for(i=1;i<=r;i++){
            for(j=1;j<=c;j++){
                pt[i][j].ansx = i;
                pt[i][j].ansy = j;
                pt[i][j].exist = true;
            }
        }
        while(n--){
            scanf("%s",cmd);
            if(cmd[0] == 'E'){
                scanf("%d%d%d%d",&r1,&c1,&r2,&c2);
                int tmpx = pt[r1][c1].ansx,tmpy = pt[r1][c1].ansy;
                pt[r1][c1].ansx = pt[r2][c2].ansx;pt[r1][c1].ansy = pt[r2][c2].ansy;
                pt[r2][c2].ansx = tmpx;pt[r2][c2].ansy = tmpy; 
            }
            else if(cmd[0] == 'D' && cmd[1] == 'C'){
                int a,x;
                scanf("%d",&a);
                while(a--){
                    scanf("%d",&x);
                    DC(x);
                }
            }
            else if(cmd[0] == 'D' && cmd[1] == 'R'){
                int a,x;
                scanf("%d",&a);
                while(a--){
                    scanf("%d",&x);
                    DR(x);
                }
            }
            else if(cmd[0] == 'I' && cmd[1] == 'C'){
                int a,x;
                scanf("%d",&a);
                while(a--){
                    scanf("%d",&x);
                    IC(x);
                }
            }
            else{
                int a,x;
                scanf("%d",&a);
                while(a--){
                    scanf("%d",&x);
                    IR(x);
                }
            }
        }
        if (kase>0) printf("\n");
        printf("Spreadsheet #%d\n",++kase);
        scanf("%d",&q);
        while(q--){
            scanf("%d%d",&r1,&c1);
            printf("Cell data in (%d,%d) ",r1,c1);
            if(!pt[r1][c1].exist) printf("GONE\n");
            else printf("move to (%d,%d)\n",pt[r1][c1].ansx,pt[r1][c1].ansy);
        }
    }
    return 0;
}

以上代码有许多重复的地方。而且因为每次搜索一个点变换后坐标都要遍历整个结构体数组,非常麻烦。看了书之后,学到了用一个值表示一对坐标的方法。

d(x,y)=x*BIG+y(BIG是一个大数,至少要大于列数的最大值maxn)

使用这样的方法能够使算法更加简洁一些。
ps:注意正确的使用memset,防止结果错误=。=

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#define maxn 100
#define BIG 1000
using namespace std;

int d[maxn][maxn],d2[maxn][maxn],r,c,n,line[maxn],ans[maxn][maxn]; 

void del(char type){
    //cout<<"I am in"<<endl; 
    int cnt = 0,i,j;
    memcpy(d2,d,sizeof(d));
    if(type == 'R'){
        for(i=1;i<=r;i++){
            if(line[i]) continue;
            cnt++;
            for(j=1;j<=c;j++){
                d[cnt][j] = d2[i][j];
            }
        }
        r=cnt;
    }
    else{
        for(j=1;j<=c;i++){
            if(line[j]) continue;
            cnt++;
            for(i=1;i<=r;j++){
                d[i][cnt] = d2[i][j];
            }
        }
        c=cnt;
    }
}

void ins(char type){
    //cout<<"I am in"<<endl; 
    int cnt = 0,i,j;
    memcpy(d2,d,sizeof(d));
    if(type == 'R'){
        for(i=1;i<=r;i++){
            if(line[i]) {
                cnt++;
                for(j=1;j<=c;j++) d[cnt][j] = 0;
            }
            cnt++;
            for(j=1;j<=c;j++){
                d[cnt][j] = d2[i][j];
            }
        }
        r=cnt;
    }
    else{
        //cout<<"I am in"<<endl; 
        for(j=1;j<=c;j++){
            if(line[j]) {
                cnt++;
                for(i=1;i<=r;i++) d[i][cnt] = 0;
            }
            cnt++;
            for(i=1;i<=r;i++){
                d[i][cnt] = d2[i][j];
            }
        }
        c=cnt;
    }
}

int main(){
    int i,j,r1,r2,c1,c2,kase=0,q;
    char cmd[10];   
    while(scanf("%d%d%d",&r,&c,&n) && r){
        memset(d,0,sizeof(d));
        for(i=1;i<=r;i++){
            for(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 tmp = d[r1][c1];d[r1][c1] = d[r2][c2];d[r2][c2] = tmp;
            }
            else{
                int a,x;
                scanf("%d",&a);
                memset(line,0,sizeof(line));
                for(i=0;i<a;i++) {
                    scanf("%d",&x);
                    line[x] = 1;
                }
                //cout<<x<<endl;
                if(cmd[0] == 'D') del(cmd[1]);
                else ins(cmd[1]);
            }
        }
        memset(ans,0,sizeof(ans));
        for(i=1;i<=r;i++){
            for(j=1;j<=c;j++)
                ans[d[i][j]/BIG][d[i][j]%BIG]= i*BIG + j;
        }
        if(kase>0) printf("\n");
        printf("Spreadsheet #%d\n",++kase);
        scanf("%d",&q);
        while(q--){
            scanf("%d%d",&r1,&c1);
            printf("Cell data in (%d,%d) ",r1,c1);
            if(ans[r1][c1]==0) printf("GONE\n");
            else printf("move to (%d,%d)\n",ans[r1][c1]/BIG,ans[r1][c1]%BIG);
        }       
    } 
    return 0;
} 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值