例题5-2木块问题 UVa101
感悟。
1、从网站下载英文原题,重点在看输入输出数据与格式。
2、借助书中中文才算看懂四条命令的英文表述。
3、结合输入输出数据进行模拟,再反复阅读输出部分英文描述,此题基本弄懂。输出的是经过一系列操作后,每个位置的木块情况。
4、开始编码。准备借助书中的不定长数组vector。不另起炉灶了,不白手起家了。
5、有一个疑问,程序是处理一次,还是循环处理。先按一次来编写,提交若无法AC,再参考他人代码。
6、因每行输入中涉及数字;每行输入或是涉及字母、数字及到多个空格的组合。故C中的字符数组已捉襟见肘,采用C++的string进行尝试,一切为了简化代码。
7、在搭输入输出框架过程中,对string,sstream进一步熟悉了,引以为豪的是接下来这两句:
stringstream ss(cmd);
ss>>op>>a>>means>>b;//字符串解析
8、关于string用法,参考了http://www.jb51.net/article/41725.htm
9、关于vector用法,参考了http://www.cnblogs.com/wang7/archive/2012/04/27/2474138.html
10、按部就班,很快编好程序,稍作调试,通过测试样例,在http://vjudge.net上提交AC,紧接着在https://uva.onlinejudge.org上提交AC。看了看时间2016-11-15 15:25
11、放心的扫了一遍书中该题的内容,发现在解析字符串上,书中与本人思路基本接近,只是本人兜了个圈。当代码量大了后,应该写函数,而不是所有内容都写一块。
附上AC代码,编译环境Dev-C++4.9.9.2
#include <cstdio>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
using namespace std;//此句要加,否则vector无法识别
const int maxn=30;
vector<int> v[maxn];
int main(){
int n;
string cmd;//命令字符串,可以接受空格
int i,j;
int a,b;
string op,means;
int ai,aj,bi,bj;
int vlen;
int t;
getline(cin,cmd);//一开始不一行一行的读取,接下来一行一行读取会有些意向不到的结果
stringstream ss(cmd);
ss>>n;
for(i=0;i<n;i++)//vector初始化
v[i].push_back(i);
while(1){
getline(cin,cmd);//读入一行
if(cmd[0]=='q')//命令结束
break;
else{
//字符串处理
stringstream ss(cmd);
ss>>op>>a>>means>>b;//字符串解析
if(a==b)//同一个木块
continue;
for(i=0;i<n;i++){//查询a、b位置
vlen=v[i].size();
for(j=0;j<vlen;j++){
if(v[i][j]==a){
ai=i;
aj=j;
}
if(v[i][j]==b){
bi=i;
bj=j;
}
}
}
if(ai==bi) //木块在同一列
continue;
if(cmd[0]=='m'){
if(means.compare("onto")==0){//==0两字符串相同
vlen=v[ai].size();
for(j=vlen-1;j>aj;j--){//将a序列,不包括a删除
t=v[ai][j];
v[t].push_back(t); //向序列为t的尾部加入t
v[ai].pop_back();//将序列为ai的尾部删除
}
v[ai].pop_back();
vlen=v[bi].size();
for(j=vlen-1;j>bj;j--){//将b序列,不包括b删除
t=v[bi][j];
v[t].push_back(t); //向序列为t的尾部加入t
v[bi].pop_back();//将序列为bi的尾部删除
}
v[bi].push_back(a);// //向序列为bi的尾部加入a
}else if(means.compare("over")==0){
vlen=v[ai].size();
for(j=vlen-1;j>aj;j--){//将a序列,不包括a删除
t=v[ai][j];
v[t].push_back(t); //向序列为t的尾部加入t
v[ai].pop_back();//将序列为ai的尾部删除
}
v[ai].pop_back();
v[bi].push_back(a);// //向序列为bi的尾部加入a
}
}else if(cmd[0]=='p'){
if(means.compare("onto")==0){//==0两字符串相同
vlen=v[bi].size();
for(j=vlen-1;j>bj;j--){//将b序列,不包括b删除
t=v[bi][j];
v[t].push_back(t); //向序列为t的尾部加入t
v[bi].pop_back();//将序列为bi的尾部删除
}
vlen=v[ai].size();
for(j=aj;j<vlen;j++){//将a序列木块拷贝到b序列
t=v[ai][j];
v[bi].push_back(t);
}
for(j=vlen-1;j>aj;j--){//将a序列,不包括a删除
v[ai].pop_back();//将序列为ai的尾部删除
}
v[ai].pop_back();//删除a
}else if(means.compare("over")==0){
vlen=v[ai].size();
for(j=aj;j<vlen;j++){//将a序列木块拷贝到b序列
t=v[ai][j];
v[bi].push_back(t);
}
for(j=vlen-1;j>aj;j--){//将a序列,不包括a删除
v[ai].pop_back();//将序列为ai的尾部删除
}
v[ai].pop_back();//删除a
}
}
}
}
//打印
for(i=0;i<n;i++){
vlen=v[i].size();
printf("%d:",i);
for(j=0;j<vlen;j++){
printf(" %d",v[i][j]);
}
printf("\n");
}
return 0;
}