这题感觉还不错,很好的练习了vector,也非常考察细心。我之前提交WA原因是因为我傻傻的以为a和b都是1位数,于是用了一个getline()
然后通过第几位的数字来读,后来看了标程之后突然恍然大悟,改过来就AC了。
我的代码:
#include <cstdio>
#include <cstring>
#include <vector>
#include <iostream>
using namespace std;
vector<int> block[25];
string c1, c2;
int n, ai, aj, bi, bj;
int a, b;
void find(int, bool);
void returns(int, bool);
inline void move();
inline void pile();
int main()
{
freopen("New Text Document.txt","r",stdin);
freopen("Output.txt","w",stdout);
ios::sync_with_stdio(false);
cin>>n;
cin.get();
//initialize
for(int i = 0; i < n; i++) block[i].push_back(i);
//get the command
while(cin>>c1>>a>>c2>>b)
{
//cout<<c<<endl;
if(c1[0] == 'q') break;
else
{
find(a, true);
find(b, false);
//cout<<a<<" "<<b<<endl;
if(ai == bi)
{
c1.clear();
c2.clear();
continue;
}
switch(c1[0])
{
case 'm':
if(c2[1] == 'n')
{
returns(a, true);
returns(b, false);
move();
}
else
{
returns(a, true);
move();
}
break;
case 'p':
if(c2[1] == 'n')
{
returns(b, false);
pile();
}
else
{
pile();
}
break;
}
}
c1.clear();
c2.clear();
}
for(int i = 0; i < n; i++)
{
cout<<i<<":";
for(int j = 0; j < block[i].size(); j++)
cout<<" "<<block[i][j];
cout<<endl;
}
return 0;
}
void find(int x, bool boo)//用bool标示 a or b
{
for(int i = 0; i < n; i++)
for(int j = 0; j < block[i].size(); j++)
if(block[i][j] == x)
{
if(boo)
{
ai = i;
aj = j;
}
else
{
bi = i;
bj = j;
}
break;
}
return;
}
//无需考虑原位被占,因为一旦被挪走,没有指令可以把积木挪回空位
void returns(int x, bool boo)//用bool标示 a or b
{
int i = boo ? ai : bi, j = boo ? aj : bj;
//for(int k = block[i].size() - 1; k > j; k--) 之前写的这个,华丽丽的错了
for(int k = j+1; k < block[i].size(); k++)
block[block[i][k]].push_back(block[i][k]);
block[i].resize(j+1);
}
inline void move()
{
block[bi].push_back(a);
block[ai].resize(aj);
}
inline void pile()
{
for(int j = aj; j < block[ai].size(); j++)
block[bi].push_back(block[ai][j]);
block[ai].resize(aj);
}
这个是刘汝佳标程,通过引用的方式传递参数进而改变main()
函数中所定义的变量,感觉比我程序中通过传递一个bool标记来区别a还是b的方式要好很多,代码也简短不少。
// UVa101 The Blocks Problem
// Rujia Liu
#include <cstdio>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
const int maxn = 30;
int n;
vector<int> pile[maxn]; // 每个pile[i]是一个vector
// 找木块a所在的pile和height,以引用的形式返回调用者
void find_block(int a, int& p, int& h) {
for(p = 0; p < n; p++)
for(h = 0; h < pile[p].size(); h++)
if(pile[p][h] == a) return;
}
// 把第p堆高度为h的木块上方的所有木块移回原位
void clear_above(int p, int h) {
for(int i = h+1; i < pile[p].size(); i++) {
int b = pile[p][i];
pile[b].push_back(b); // 把木块b放回原位
}
pile[p].resize(h+1); // pile只应保留下标0~h的元素
}
// 把第p堆高度h及其上方的木块整体移动到p2堆的顶部
void pile_onto(int p, int h, int p2) {
for(int i = h; i < pile[p].size(); i++)
pile[p2].push_back(pile[p][i]);
pile[p].resize(h);
}
void print() {
for(int i = 0; i < n; i++) {
printf("%d:", i);
for(int j = 0; j < pile[i].size(); j++) printf(" %d", pile[i][j]);
printf("\n");
}
}
int main() {
int a, b;
cin >> n;
string s1, s2;
for(int i = 0; i < n; i++) pile[i].push_back(i);
while(cin >> s1 >> a >> s2 >> b) {
int pa, pb, ha, hb;
find_block(a, pa, ha);
find_block(b, pb, hb);
if(pa == pb) continue; // 非法指令
if(s2 == "onto") clear_above(pb, hb);
if(s1 == "move") clear_above(pa, ha);
pile_onto(pa, ha, pb);
}
print();
return 0;
}