【题目】
有一个5*5的网络,恰好有一个格子是空的(空格),其他格子各有一个字母。
指令:A, B, L, R 把空格上、下、左、右的相邻字母移到空格中。
【输入】
初始网格和指令序列(以数字0结束)。
【输出】
指令执行完毕后的网格。
如果有非法指令,输出"This puzzle has no final configuration."。
【知识点】
-
scanf输入带空格的输入,scanf的多次使用
https://www.cnblogs.com/kinologic/p/13957927.html -
二维数组的传参方式
https://www.cnblogs.com/kinologic/p/13958685.html
我这里用了文章中的第二种方式。第一种方式和第二种方式都还比较简单。第三种方法要用到二级指针了,略显复杂。
首先是在主函数中定义了二维数组:
其次是在子函数中的引用:
-
switch-case分支语句一定要写break!
break的作用是结束当前的switch语句,如果删去,则程序将会从第一个匹配的case开始执行语句,直到其下面的所有语句都执行完毕才会退出switch。 -
多组数据的返回
刚开始写的时候脑子不太好用,看有用结构体/传指针的方式。
但是后来意识到有小题大做了,其实直接用C++引用传int的引用就行了。 -
二维数组的坐标
a[x][y]
x是行,y是列
修改行:x 上- 下+
修改列:y 左- 右+
【代码】
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
const int maxn = 100;
using namespace std;
void alert()
{
printf("This puzzle has no congiruation
");
}
void show_matrix(char(*a)[10])
{
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
printf("%c", a[i][j]);
}
printf("
");
}
}
void get_empty(char(*a)[10], int& x, int& y) //由于对值由修改,必须传引用
{
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
if (a[i][j] == ' ') //if后面两句要打括号,不然只会执行一句
{
x = i;
y = j;
}
}
}
}
void move_empty(char c, char(*a)[10], int& x, int& y) //对值没有修改,不传引用也可以
{
switch(c)
{
case 'A': //把空格上方的相邻字母移到空格中
{
if (x == 0) alert();
else
{
a[x][y] = a[x-1][y];
a[x-1][y] = ' ';
}
}
break;
case 'B': //把空格下方的相邻字母移到空格中
{
if (x == 4) alert();
else
{
a[x][y] = a[x+1][y];
a[x+1][y] = ' ';
}
}
break;
case 'L': //把空格左方的相邻字母移到空格中
{
if (y == 0) alert();
else
{
a[x][y] = a[x][y-1];
a[x][y-1] = ' ';
}
}
break;
case 'R': //把空格右方的相邻字母移到空格中
{
if (y == 4) alert();
else
{
a[x][y] = a[x][y+1];
a[x][y+1] = ' ';
}
}
break;
}
}
int main()
{
char s[maxn]; //暂存用
char a[10][10]; //存储题目矩阵,a是二维数组(二级指针)
//坐标参数指针
int x = 0, y = 0; //位置坐标
//输入题目矩阵:五行输入 带空格
for (int i = 0; i < 5; i++)
{
scanf("%[^
]",s);
for (int j = 0; j < 5; j++)
{
a[i][j] = s[j];
}
fflush(stdin);
}
//printf("out
");
//show_matrix(a);
//输入指令序列
fflush(stdin);
scanf("%s",s);
int n = strlen(s);
//检测是否为合法指令
int flag = 1;
for (int i = 0; i < n-1; i++)
{
if(s[i] != 'A' && s[i] != 'B' && s[i] != 'L' && s[i] != 'R') //用“或”有错误
{
flag = 0;
break;
}
}
//printf("1flag %d
",flag);
if ( s[n-1] != '0' ) flag = 0;
//printf("2flag %d
",flag);
if (flag == 0) alert();
//若为合法指令
else
{
for (int i = 0; i < n-1; i++)
{
get_empty(a, x, y);
printf("empty: x is %d, y is %d
", x, y);
move_empty(s[i], a, x, y); //执行命令
}
show_matrix(a);
}
system("pause");
}
【心得】
C的指针真是太麻烦了,用不起就用C++的引用(