「UVA177」折纸痕 Paper Folding
[UVA177] Paper Folding
Problem Statement
给定一张无限大的纸,从右往左对折
数据范围:
Solution
考虑每次展开
而最终会展开
不难发现,这一次会在上一次的基础上倒着再做一遍,只是这时候方向都逆时针旋转了
- 倒着做一遍是向右,方向逆时针旋转
90\degree 为向上:向右向上。 - 倒着做一遍是向上向右,方向逆时针旋转
90\degree 为向左向上:向右向上向左向上。 - 倒着做一遍是向上向左向上向右,方向逆时针旋转
90\degree 为向左向下向左向上:向右向上向左向上向左向下向左向上。 - ……
接下来考虑实现,由于并不知道图究竟有多大。所以,直接开
时间复杂度:
Code
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
while (cin >> n && n) {
vector<vector<char>> ans(1000, vector<char>(1000, ' '));
vector<vector<int>> dx = {{1, 1}, {1, -1}, {-1, -1}, {1, -1}}, dy = {{0, 1}, {-1, -1}, {0, 1}, {0, 0}};
ans[500][500] = '_';
int x = 500, y = 500, lst = 0;
vector<int> sd = {0};
while (n -- ) {
vector<int> cur;
reverse(sd.begin(), sd.end());
for (auto v : sd) {
int u = (v + 1) % 4;
x += dx[lst][u / 2], y += dy[lst][u / 2];
if (u % 2 == 0) ans[y][x] = '_';
else ans[y][x] = '|';
cur.push_back(u), lst = u;
}
reverse(sd.begin(), sd.end());
sd.insert(sd.end(), cur.begin(), cur.end());
}
int lx = 2000, ly = 2000, rx = -1;
vector<int> r(1000);
for (int i = 1; i < 1000; i ++)
for (int j = 1; j < 1000; j ++)
if (ans[i][j] != ' ') {
lx = min(lx, i), ly = min(ly, j);
rx = max(rx, i), r[i] = max(r[i], j);
}
for (int i = lx; i <= rx; i ++) {
for (int j = ly; j <= r[i]; j ++)
cout << ans[i][j];
cout << endl;
}
cout << "^\n";
}
}