题目:
题意:有一个5*5的网格,其中恰好有一个格子是空的,其他格子各有一个字母。一共有4种指令:A, B, L, R,分别表示把空格上、下、左、右的相邻字母移到空格中。输入初始网格和指令序列(以数字0结束),输出指令执行完毕后的网格。如果有非法指令,应输出“This puzzle has no final configuration.”如下图所示:分别为执行ARRBBL0前、后的效果图:
Sample Input:
TRGSJ
XDOKI
M VLN
WPABE
UQHCF
ARRBBL0
ABCDE
FGHIJ
KLMNO
PQRS
TUVWX
AAA
LLLL0
ABCDE
FGHIJ
KLMNO
PQRS
TUVWX
AAAAABBRRRLL0
Z
Sample Output:
Puzzle #1:
T R G S J
X O K L I
M D V B N
W P A E
U Q H C F
Puzzle #2:
A B C D
F G H I E
K L M N J
P Q R S O
T U V W X
Puzzle #3:
This puzzle has no final configuration.
注意事项:
本题中不能简单的使用cin>>来读取数据:读取初始网格时,注意读取一行带有空格的指令;读取指令时,遇到“0”才截至,注意将多行读入的指令处理为一行指令。
cin.get():从输入缓冲区读取单个字符串,且不忽略分隔符。
cin.get(char *s, size_t n);
cin.get(char *s, size_t n, streamsize delim);
//读取一行,n为目标空间大小,delim指定结束符。
1. getline()的原型是(定义在istream中的成员函数)
cin.getline(char *s, size_t n);
cin.getline(char *s, size_t n, char delim);
//读取一行,不会将结束符或者换行符残留在输入缓冲区。
cin>>:可连续从键盘读取想要的数据(以空格、tab或者换行作为风额符)。
2. getline()的原型是(定义在string头文件中的一个全局函数)
istream& getline ( istream &is , string &str );
istream& getline ( istream &is , string &str , char delim );
//istream &is 表示一个输入流,譬如cin;string&str表示把从输入流读入的字符串存放在这个字符串中;char delim表示遇到这个字符停止读入,在不设置的情况下系统默认该字符为’\n’,也就是回车换行符。
编程总结:
- 为重复实现的功能编写小函数调用:如,在执行每一步指令时,可以调用执行一步指令的函数;
- 处理读入的网格数组中的空格,分行将读入的字符串写入到网格数组中;
- “全局变量”与“局部变量”的处理:将5*5网格存储为全局变量,方便函数的处理;
程序代码:
#include<iostream>
#include<string>
using namespace std;
//全局变量:存放5*5网格相关数据
char puzzle[6][6];//存放网格数组
int x0, y0;//存放空格的位置(下标从0开始),第x行,第y列
//将读入的一串字符串分别存储到网格数组中去
void read(int row, string str) {
for (int i = 0; i < 5; i++) {
puzzle[row][i] = str[i];
if (str[i] == ' ') {
x0 = row;
y0 = i;
}
}
}
bool move(char order) {
int x, y;//移动后空格的坐标
switch (order)
{
//上
case 'A':
x = x0 - 1; y = y0;
break;
//下
case 'B':
x = x0 + 1; y = y0;
break;
//左
case 'L':
x = x0; y = y0 - 1;
break;
//右
case 'R':
x = x0; y = y0 + 1;
break;
default:
break;
}
if ((x >= 0 && x <= 4) && (y >= 0 && y <= 4)) {
puzzle[x0][y0] = puzzle[x][y];
puzzle[x][y] = ' ';
x0 = x; y0 = y;
return true;
}
else {
return false;
}
}
int main()
{
string order;//存放指令序列
string str;//输入网格数组时的中间存储量
int icase = 0;//求解问题的次数
while (1) {
if (icase != 0)
cin.get();//读取掉输入缓冲区的换行符
//读取一行字符并处理
getline(cin, str);
if (str[0] == 'Z')
break;
//不同样例间换行
if (icase != 0)
cout << endl;
read(0, str);
for (int i = 1; i <= 4; i++) {
getline(cin, str);
read(i, str);
}
//读取指令序列
order.clear();
int len;
while (true) {
string temp;
cin >> temp;
order += temp;
len = order.length();
if (order[len - 1] == '0')
break;
}
//看是否有解
bool has_result = true;
for (int i = 0; i < len - 1; i++) {
if (move(order[i]) == false) {
has_result = false;
break;
}
}
cout << "Puzzle #" << ++icase << ":" << endl;
if (has_result) {
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 4; j++) {
cout << puzzle[i][j] << " ";
}
cout << puzzle[i][4] << endl;
}
}
else {
cout << "This puzzle has no final configuration." << endl;
}
}
system("pause");
return 0;
}