题意及分析:
- 给定一个两个数n和m,代表一个表格的行数和列数。
- 给定几个操作:DR(删除此行),DC(删除此列),IR(添加新行),IC(添加新列),EX(交换两个坐标)。
(特别需要注意的是:例如同一次DR删除多行,都是在原表格操作的,并不是删除一行后在新列表进行下一次删除。)- 给定几次询问,每次询问输入一个坐标(行,列),问初始表格的这个位置到了最终表格的哪个位置。
解题思路:
首先将这个n*m的表格每个位置赋上初始值(可看具体init函数实现)
EX操作用swap函数直接交换两个值即可。
其余四个操作,读入并存储所有操作数,进行排序,从大到小进行相应操作。(从大到小的好处是当前操作不会受到之前操作的影响)
附代码:
#include <set> #include <map> #include <cmath> #include <stack> #include <queue> #include <vector> #include <string> #include <cstdio> #include <cstring> #include <sstream> #include <iomanip> #include <iostream> #include <algorithm> #define clr(str,x) memset(str,x,sizeof(str)) #define FRER() freopen("in.txt","r",stdin); #define FREW() freopen("out.txt","w",stdout); #define MAX_INF 0x7fffffff #define INF 0x3f3f3f3f #define maxn 55 typedef long long int ll; using namespace std; int n,m,x; int a[maxn][maxn]; int Maxr,Maxc; void init() { clr(a,0); for(int i=1; i<=n; i++) { for(int j=1; j<=m; j++) { a[i][j] = (i-1)*m+j; } } } void Copy(bool op,int p1,int p2)//将p2行或列赋值给p1 { if(op) // 行 { for(int i=1; i<=Maxc; i++) a[p1][i]=a[p2][i]; } else // 列 { for(int i=1; i<=Maxr; i++) a[i][p1]=a[i][p2]; } } void del_r()//删除行 { vector<int> v; int cnt,num=0; scanf("%d",&cnt); for(int i=0; i<cnt; i++) { scanf("%d",&x); v.push_back(x); } sort(v.begin(),v.end()); for(int i=v.size()-1; i>=0; i--) { x=v[i]; if(x>Maxr||x<=0) continue; for(int j=x; j<Maxr; j++) { Copy(true,j,j+1); } num++; } for(int i=Maxr,j=0; j<num; i--,j++) { for(int l=0; l<maxn; l++) a[i][l]=0; } Maxr-=num; } void del_c()//删除列 { vector<int> v; int cnt,num=0; scanf("%d",&cnt); for(int i=0; i<cnt; i++) { scanf("%d",&x); v.push_back(x); } sort(v.begin(),v.end()); for(int i=v.size()-1; i>=0; i--) { x=v[i]; if(x>Maxc||x<=0) continue; for(int j=x; j<Maxc; j++) { Copy(false,j,j+1); } num++; } for(int i=Maxc,j=0; j<num; i--,j++) { for(int l=0; l<maxn; l++) a[l][i]=0; } Maxc-=num; } void ins_r()//添加行 { vector<int> v; int cnt,num=0; scanf("%d",&cnt); for(int i=0; i<cnt; i++) { scanf("%d",&x); v.push_back(x); } sort(v.begin(),v.end()); for(int i=v.size()-1; i>=0; i--) { x=v[i]; if(x>Maxr+1||x<=0) continue; for(int j=Maxr+num; j>=x; j--) { Copy(true,j+1,j); } for(int j=0; j<maxn; j++) a[x][j]=-1; num++; } Maxr+=num; } void ins_c()//添加列 { vector<int> v; int cnt,num=0; scanf("%d",&cnt); for(int i=0; i<cnt; i++) { scanf("%d",&x); v.push_back(x); } sort(v.begin(),v.end()); for(int i=v.size()-1; i>=0; i--) { x=v[i]; if(x>Maxc+1||x<=0) continue; for(int j=Maxc+num; j>=x; j--) { Copy(false,j+1,j); } for(int j=0; j<maxn; j++) a[j][x]=-1; num++; } Maxc+=num; } void ex()//交换两个位置上的数 { int p1,p2,p3,p4; scanf("%d%d%d%d",&p1,&p2,&p3,&p4); swap(a[p1][p2],a[p3][p4]); } int main() { //FRER() //FREW(); int kase=1,k; char op[2]; while(scanf("%d%d",&n,&m)) { if(n==0&&m==0) break; Maxr=n,Maxc=m; init(); scanf("%d",&k); getchar(); while(k--) { op[0]=getchar(); op[1]=getchar(); if(op[0]=='D'&&op[1]=='R') del_r(); else if(op[0]=='D'&&op[1]=='C') del_c(); else if(op[0]=='I'&&op[1]=='R') ins_r(); else if(op[0]=='I'&&op[1]=='C') ins_c(); else if(op[0]=='E'&&op[1]=='X') ex(); getchar(); } int nn; scanf("%d",&nn); int p1,p2,p3,p4; if(kase!=1) //控制格式 printf("\n"); printf("Spreadsheet #%d\n",kase++); for(int i=0; i<nn; i++) { scanf("%d%d",&p1,&p2); int ok=0; int temp = m*(p1-1)+p2; for(int j=1; j<=Maxr; j++) { for(int k=1; k<=Maxc; k++) { if(a[j][k]==temp) { p3=j,p4=k; ok=1; break; } } if(ok) break; } if(ok) printf("Cell data in (%d,%d) moved to (%d,%d)\n",p1,p2,p3,p4); else printf("Cell data in (%d,%d) GONE\n",p1,p2); } } return 0; }