赞
踩
题目大意:
一张纸,不断从右往左对折n次, 原来的大纸会变成一个窄窄的纸条。现在把纸条沿折痕打开,每次打开“一半”, 即把每个痕迹做成一个直角,将最下面的纸水平放置保持不变,展开后沿着纸面平行的方向会形成一个美妙的曲线,输出曲线。
思路:
n = 1时 路径:ru
n = 2时 路径:rulu
n = 3时 路径:rululdlu
n = 4时 路径:rululdluldrdldlu
规律:每次构造前半部分相反,后半部分相同
所以可以定义一个大数组,初始点在数组中间,然后沿着路径构造
max_c数组存每行的最大行,防止输出多余的空格。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 50000;
char mp[maxn][2000];
int max_c[maxn];
int n;
int main() {
//freopen("D:\\input.txt", "r", stdin);
// freopen("D:\\output.txt", "w", stdout);
ios::sync_with_stdio(false), cin.tie(0);
while(cin >> n, n) {
memset(mp, '\0', sizeof(mp));
for(int i = 0; i < maxn; i++) max_c[i] = -2000;
string s = "ru";
for(int i = 2; i <= n; i++) {
int len = s.length();
for(int j = 0; j < len; j++) {
if(j < len / 2) {
if(s[j] == 'r') s += "l";
else if(s[j] == 'l') s += "r";
else if(s[j] == 'u') s += "d";
else if(s[j] == 'd') s += "u";
}
else s += s[j];
}
}
//cout << s << "QAQ" << endl;
int cur_r = 25000, cur_c = 1000;
int max_r = 25000, min_r = 25000, min_c = 1000;
max_c[25000] = 1000;
mp[cur_r][cur_c] = '_';
for(int i = 1; i < s.length(); i++) {
if(s[i-1] == 'r') {
if(s[i] == 'u') {
cur_c++;
mp[cur_r][cur_c] = '|';
}
else if(s[i] == 'd') {
cur_c++;
cur_r++;
mp[cur_r][cur_c] = '|';
}
}
else if(s[i-1] == 'l') {
if(s[i] == 'u') {
cur_c--;
mp[cur_r][cur_c] = '|';
}
else if(s[i] == 'd') {
cur_c--;
cur_r++;
mp[cur_r][cur_c] = '|';
}
}
else if(s[i-1] == 'u') {
if(s[i] == 'l') {
cur_c--;
cur_r--;
mp[cur_r][cur_c] = '_';
}
else if(s[i] == 'r') {
cur_c++;
cur_r--;
mp[cur_r][cur_c] = '_';
}
}
else if(s[i-1] == 'd') {
if(s[i] == 'l') {
cur_c--;
mp[cur_r][cur_c] = '_';
}
else if(s[i] == 'r') {
cur_c++;
mp[cur_r][cur_c] = '_';
}
}
min_r = min(min_r, cur_r);
max_r = max(max_r, cur_r);
min_c = min(min_c, cur_c);
max_c[cur_r] = max(max_c[cur_r], cur_c);
}
for(int i = min_r; i <= max_r; i++) {
for(int j = min_c; j <= max_c[i]; j++) {
if(mp[i][j] == '\0') printf(" ");
else printf("%c", mp[i][j]);
}
printf("\n");
}
printf("^\n");
}
return 0;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。