1、题目大意
题目链接UVa101
2、解题思路
开一个二维数组,直接进行模拟即可。
3、参考代码
#include<iostream>
#include<string>
#include<cstring>
using namespace std;
int ans[30][30];
int find_block(int s[30][30], int a) {
for (int i = 0; i < 30; i++)
for (int j = 0; j < 30; j++)
if (s[i][j] == a)
return i;
}
void return_back(int s[30][30], int pa, int a) {
int i;
for (i = 0; i < 30; i++)
if (s[pa][i] == a) break;
for (i += 1; i < 30; i++)
if (s[pa][i] >= 0) {
int t = s[pa][i];
for (int j = 0; j < 30; j++)
if (s[t][j] == -1) { s[t][j] = t; break; }
s[pa][i] = -1;
}
}
void move_block(int s[30][30], int pa, int a, int pb, int b) {
int i, j;
for (i = 0; i < 30; i++) if (s[pa][i] == a) break;
for (j = 0; j < 30; j++) if (s[pb][j] == -1) break;
for (; i < 30; i++, j++)
if (s[pa][i] >= 0) {
s[pb][j] = s[pa][i];
s[pa][i] = -1;
}
}
int main() {
int n, a, b;
memset(ans, -1, sizeof(ans));
string s1, s2;
cin >> n;
for (int i = 0; i < n; i++) { ans[i][0] = i; }
while (cin >> s1, s1 != "quit") {
cin >> a >> s2 >> b;
int pa = find_block(ans, a);
int pb = find_block(ans, b);
if (pa == pb) continue;
if (s1 == "move") return_back(ans, pa, a);
if (s2 == "onto") return_back(ans, pb, b);
move_block(ans, pa, a, pb, b);
}
for (int i = 0; i < n; i++) {
cout << i << ':';
for (int j = 0; j < n; j++)
if (ans[i][j] >= 0)
cout << ' ' << ans[i][j];
cout << endl;
}
return 0;
}
4、解题感悟
- 第一次提交 Compile Error。仔细阅读错误代码,发现是因为 memset() 函数没有定义。在C++ 中,memset() 包含在头文件 cstring 中,而不是 string 中。
- 第二次提交Runtime Error,就是程序运行到一半出错,崩溃了。常见的原因有:
(1) 除以0;
(2)数组越界;
(3)指针越界;
(4)使用已经释放的空间;
(5)数组开得太大,造成栈溢出。一般数组设为全局变量,减少栈溢出可能性。
仔细检查了代码,发现是 move_block 函数中数组越界了,改正后提交AC。 - 刘大爷书中使用了 STL 中的不定长数组 vector,代码紧凑,编写简单,思路清晰。我应当尝试多用 STL 实现代码。