解决本题最直接的思路是:先模拟增删交换操作,算出最后电子表格的状态,然后执行每次查询.这种方法不仅效率低而且不容易理解
另一种思路,直接追踪要查询的单元格,不用关心整个单元格的变化.
详细注释完整代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <assert.h>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define maxd 10000
struct Command{
char c[5];//用于输入指令
int r1,c1,r2,c2;//用于交换位置的点
int a,x[20];//用于输入增删行列和个数
}cmd[maxd];
int r,c,n;//电子单元的行列数,和指令数
int simulate(int* r0,int* c0)
{
for(int i=0;i<n;i++){
if(cmd[i].c[0]=='E'){//交换位置,有两个(r1,c1),(r2,c2)
if(cmd[i].r1==*r0&&cmd[i].c1==*c0){
*r0=cmd[i].r2;
*c0=cmd[i].c2;
}
else if(cmd[i].r2==*r0&&cmd[i].c2==*c0){
*r0=cmd[i].r1;
*c0=cmd[i].c1;
}
}
else{//非交换也即增删
int dr=0,dc=0;//记录有效的增删个数
for(int j=0;j<cmd[i].a;j++){
int x=cmd[i].x[j];//记录要进行操作的某一行或列
if(cmd[i].c[0]=='I'){//增
if(cmd[i].c[1]=='R'&&x<=*r0) dr++;//增加的那一行在所要查找的那一行的前面(或等于) ,那么有效也即++
if(cmd[i].c[1]=='C'&&x<=*c0) dc++;//增加的那一列在所要查找的那一列的前面(或等于) ,那么有效也即++
}
else{//删
if(cmd[i].c[1]=='R'&&x==*r0) return 0;//删除的那一行刚好是所要查找的那一行 ,那么此查询无效
if(cmd[i].c[1]=='C'&&x==*c0) return 0;//删除的那一列刚好是所要查找的那一列 ,那么此查询无效
if(cmd[i].c[1]=='R'&&x<*r0) dr--;//删除的那一行在所要查找的那一行的前面 ,那么有效也即--
if(cmd[i].c[1]=='C'&&x<*c0) dc--;//删除的那一列在所要查找的那一列的前面 ,那么有效也即--
}
}
*r0+=dr;//变化后新的位置
*c0+=dc;
}
}
return 1;
}
int main(int argc, char** argv){//输入控制
int r0,c0,q,kase=0;
while(cin>>r>>c>>n&&r){
for(int i=0;i<n;i++){
cin>>cmd[i].c;
if(cmd[i].c[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];
}
}
if(kase>0) cout<<endl;
cout<<"Spreadsheet #"<<++kase<<endl;
cin>>q;
while(q--){
cin>>r0>>c0;
cout<<"Cell data in("<<r0<<","<<c0<<")";
if(!simulate(&r0,&c0)) cout<<"GONE"<<endl;
else cout<<"move to("<<r0<<","<<c0<<")"<<endl;
}
}
return 0;
}
附:
//if与else if的区别
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
int i,j;
i=99;
j=0;
if(i==99) cout<<"a"<<endl;
//if(j==0) cout<<"b"<<endl;
else if(j==0) cout<<"c"<<endl;//if(i==99)正确的话将不执行else下的if
return 0;
}