牛客网之“折纸问题”

昨天在看左程云数据结构视频时遇到一道折纸问题,当时比较感兴趣,并对问题进行分析提取关键点进而通过代码实现。 内容分为:题目描述、问题分析、解决问题和代码描述四大部分。

题目描述

折纸问题

【题目】 请把一段纸条竖着放在桌子上,然后从纸条的下边向上方对折1次,压出折痕后展开。此时 折痕是凹下去的,即折痕突起的方向指向纸条的背面。如果从纸条的下边向上方连续对折2 次,压出折痕后展开,此时有三条折痕,从上到下依次是下折痕、下折痕和上折痕。给定一 个输入参数N,代表纸条都从下边向上方连续对折N次,请从上到下打印所有折痕的方向。 例如:N=1时,打印: down      N=2时,打印: down down up

简要说:将纸条从下往上对折N次,由上往下产生的折痕方向序列。

问题分析

对问题进行步骤分析如下:

1. 首先,要对问题进行详细剖析的前提是拿张纸对折几次并从中发现规律。

2. 其次就是进行试验,发现对折1次时折痕为1方向为down,对折2次时折痕为3方向为down down up,对折3次时折痕为7方向为down down up down down up up,对折4次时折痕为15方向为down down up down down up up down down down up up down up up。

3. 最后从结果中找出规律,完成编码。

解决问题

在这里给张图就可以清晰的把问题解决掉。


从结果中分析:第一次折纸后方向为down,第二次折纸后围绕第一次结果从上往下增加了down和up,第三次结果围绕第二次结果(不包括第一次)每个折痕多了down和up。假定我们猜想,通过实验分析和验证第四次结果正确性。明显结果正确,猜想成立。

代码描述

直接上代码:

/*
	折纸问题
	【题目】 请把一段纸条竖着放在桌子上,然后从纸条的下边向
	上方对折1次,压出折痕后展开。此时 折痕是凹下去的,即折痕
	突起的方向指向纸条的背面。如果从纸条的下边向上方连续对折
	2 次,压出折痕后展开,此时有三条折痕,从上到下依次是下折
	痕、下折痕和上折痕。
	给定一 个输入参数N,代表纸条都从下边向上方连续对折N次,
	请从上到下打印所有折痕的方向。 例如:N=1时,打印: down
	N=2时,打印: down down up
*/
#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
using namespace std;

vector<string> origima_problem(int N);

int main(void)
{
	int N = 0;
	while (cin >> N) {
		vector<string> result = origima_problem(N);

		cout << "折纸状况(共" << result.size() << ")次:" << endl;
		vector<string>::iterator it;
		for (it = result.begin(); it != result.end(); ++it) {
			cout << setw(5) << *it;
		}
		cout << endl;
	}
}
vector<string> origima_problem(int N) {
	vector<string> result, tmp;
	string down = "down", up = "up";
	for (int i = 1; i <= N; ++i) {
		tmp.erase(tmp.begin(), tmp.end());
		if (i <= 1) {
			result.push_back("down");
			continue;
		}
		for (int i = 0; i < result.size(); ++i) {
			if (i % 2 != 0) {
				tmp.push_back(result[i]);
			}
			else {
				tmp.push_back(down);
				tmp.push_back(result[i]);
				tmp.push_back(up);
			}
		}
		result.swap(tmp);
	}
	return result;
}

从代码中,我们可以看出规避了上上一个折痕。这样就达到了预期设想的结果。

思考:如果对折方向发生变化,多个方向会怎么样。


猜你喜欢

转载自blog.csdn.net/u011687724/article/details/80671596