知识到了瓶颈期[旺柴],所以继续发布中等题题解。
今天的题是Openjudge 1.8.23 二维数组贪吃蛇形遍历问题,一道中规中矩的二维数组应用。
今天的题解中我分析了一种方法,还在结尾附上了用提高方法(队列)解题的源代码。
不知道屏幕前的各位,这个题处在什么状态呢?
先看题
题面分析
1.输入时有row行,每行col个数据。所以肯定是用循环控制对应元素的输入。
2.由于是遍历,所以肯定要定义两个变量,充当坐标的迭代器。但是一定别忘了初始化。
3.想要输出遍历结果,可以直接输出对应坐标的元素,也可以存到一个一维数组(下文称之为输出数组)里(当然队列也没问题)。但由于前者相较而言略复杂,所以不作讲解,我们讲解后一种方法。那么既然要存在数组中,当然有需要一个控制坐标的变量。
说到这里,就只剩最复杂的遍历部分了。
估计大家在做这个题时都会想到CCF基础篇教材中的二维数组回形写入(贪吃蛇题),所以也做了这道题。但无奈何
出来这个结果,实则说明这个题相比母题还是有难度,但问题难度在哪呢?
母题中,写入二维数组的条件,只要某个空间还在要求的数组范围内,并且为0就可以写入,如果到了边界直接转向,而且输出时直接按普通格式输出;但本题如果这样设置,他会围绕外围无限旋转。所以,一个方法是用另一个布尔数组控制是否已读。
应该是这样的:现将数组的第一个元素手动填入输出数组里,然后判断下一个位置,如果值已读或到了边界,就转向,并将布尔数组的对应值设置好。如果所有的值都已经读取呢?那么就该停止了。
所以此处
到此,我应该使用嵌套循环。
上代码
#include<bits/stdc++.h>
using namespace std;
int a[200][200];
bool b[200][200];
int c[40000];
int main()
{
int row, col;
int x = 1, y = 1;
int cnt = 1;
cin >> row >> col;
for (int i = 1; i <= row; i++)
for (int j = 1; j <= col; j++)
cin >> a[i][j];
c[1] = a[1][1], b[1][1] = true;
while (cnt < row * col)
{
while (y + 1 <= col && !b[x][y + 1]) c[++cnt] = a[x][++y], b[x][y] = true;
while (x + 1 <= row && !b[x + 1][y]) c[++cnt] = a[++x][y], b[x][y] = true;
while (y - 1 >= 1 && !b[x][y - 1]) c[++cnt] = a[x][--y], b[x][y] = true;
while (x - 1 >= 1 && !b[x - 1][y]) c[++cnt] = a[--x][y], b[x][y] = true;
}
for (int i = 1; i <= row * col; i++)
cout << c[i] << endl;
return 0;
}
需要注意
数组有row列col行,但因为后面有一句话,“从array[0][0]元素开始”,所以有的同志写的时候可能会强按照的来,让下标从0开始,又在写循环条件时减了1。但是,实际上
(选自百度百科)
据我所知,能够察看源代码的的代码评测机并不常见(实际上常见的平台基本没有具备这项功能的)。所以,一些更利于你理清编程逻辑的代码习惯,可以考虑是否保留下来;如果对算法实现没有影响,可以考虑使用自己独特的习惯。
不同的解法
上一个分析方法中的输出数组,也可以用队列实现。
#include<bits/stdc++.h>
using namespace std;
int a[200][200];
bool b[200][200];
queue<int> q;
int main()
{
int r, c;
int x = 1, y = 1;
cin >> r >> c;
for (int i = 1; i <= r; i++)
for (int j = 1; j <= c; j++)
cin >> a[i][j];
q.push(a[1][1]), b[1][1] = true;
while (q.size() < r * c)
{
while (y + 1 <= c && !b[x][y + 1]) q.push(a[x][++y]), b[x][y] = true;
while (x + 1 <= r && !b[x + 1][y]) q.push(a[++x][y]), b[x][y] = true;
while (y - 1 >= 1 && !b[x][y - 1]) q.push(a[x][--y]), b[x][y] = true;
while (x - 1 >= 1 && !b[x - 1][y]) q.push(a[--x][y]), b[x][y] = true;
}
while (q.size()) cout << q.front() << endl, q.pop();
return 0;
}
你们还有其他的方法吗?