Openjudge 1.8.23(二维数组回形遍历) 解析

知识到了瓶颈期[旺柴],所以继续发布中等题题解。

今天的题是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;
}

你们还有其他的方法吗?

  • 17
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值