177 - Paper Folding (找规律)

一开始看这题感觉无从下手,甚至一开始根本没理解题意 。后来明白了,是一张纸,每次都是从右向左折叠,注意折叠后不要动 。

折叠完n次后,最底下那一个纸条要保持原位置不动(水平放置),其他的按题目要求展开,从侧面就会看到一条连续的“美丽”曲线 。

那么怎么样找到这条曲线呢? 其实是有规律可循的 。我们把边看作路径,那么行走的方向命令就可以写出了 。 如下:

n = 1 --> ru

n = 2 --> rulu

n = 3 --> rululdlu

n = 4 --> rululdluldrdldlu

其中udlr分别是上下左右 。

发现规律了吧? 没错,每一次都会增加一倍的步数,而且对于增加的那部分,前一半和上一次的相反,后一半相同 。

那么就不难写出了,当然绘制图像还是有点麻烦的,不过我们可以事先将数组开大一点,取中间的一个点为起始点进行绘图 。  当然,需要注意每一行的最大列都需要记录,不然会多输出很多空格,导致WA

细节参见代码:

#include<bits/stdc++.h>
using namespace std;
int n;
char s[50000][2000]; //开一个足够大的图像
int main() {
    while(~scanf("%d",&n)&&n) {
        memset(s,0,sizeof(s));
        int cnt = 1;
        char buf[50000];//行走命令
        buf[1] = 'r'; buf[2] = 'u'; buf[3] = '\0';
        while(cnt<n) {     // 记录行走方向命令
            int len = strlen(buf+1);
            for(int i=1;i<=len;i++) {
                if(i<=len/2) {
                    if(buf[i] == 'l') buf[i+len] = 'r';
                    else if(buf[i] == 'r') buf[i+len] = 'l';
                    else if(buf[i] == 'u') buf[i+len] = 'd';
                    else buf[i+len] = 'u';
                }
                else buf[i+len] = buf[i];
            }
            cnt++; buf[len*2+1] = '\0';
        }
       int min_r = 25000,max_r = 25000,min_c,max_c[50000];//按照命令,绘制图像 。 
       for(int i=1;i<=25000;i++) {  max_c[i] = -2000; }
       int cur_r = 25000,cur_c = 1000; min_c = 1000; max_c[25000] = 1000;
       int len = strlen(buf+1);
       s[cur_r][cur_c] = '_';
       for(int i=2;i<=len;i++) {
            if(buf[i-1]=='r') {
                if(buf[i]=='u') { cur_c++; s[cur_r][cur_c] = '|'; }
                else if(buf[i]=='d') { cur_r++; cur_c++; s[cur_r][cur_c] = '|'; }
            }
            else if(buf[i-1]=='l') {
                if(buf[i]=='u') { cur_c--; s[cur_r][cur_c] = '|'; }
                else { cur_r++; cur_c--; s[cur_r][cur_c] = '|' ;}
            }
            else if(buf[i-1]=='u') {
                if(buf[i]=='r') { cur_r--; cur_c++; s[cur_r][cur_c] = '_'; }
                else { cur_r--; cur_c--; s[cur_r][cur_c] = '_'; }
            }
            else {
                if(buf[i]=='r') { cur_c++; s[cur_r][cur_c] = '_'; }
                else { cur_c--; s[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);
       } //打印图像,注意每一行的最大列都要记录,否则多输出的空格会导致WA
       for(int i=min_r;i<=max_r;i++) {
          for(int j=min_c;j<=max_c[i];j++) {
            if(s[i][j] == 0) printf(" ");
            else printf("%c",s[i][j]);
          }
          printf("\n");
       }
        printf("^\n");
    }
    return 0;
}



  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值