龙曲线

龙曲线介绍

龙曲线是以简单的数学规则画出一种曲线,它具有以下形态。曲线从一个简单的线段起始,按照一定规则变换此线段完成整个曲线。每形成一次变换称为“完成了一次变换代”,而每完成一代,曲线会进化到更复杂的形式。像这种“放大其一小部分的形状时,表现出与整个形状极为相似构造的图形”,就是分形。
画出龙曲线的方法暂且就称为龙曲线字符串吧!龙曲线字符串由X、Y、F、+、-组成。
那么,要画出龙曲线就从一个点起始画出如下曲线即可。
 
F:向前方移动一格并画线。
+:向左旋转90度。
-:向右旋转90度。
X、Y:忽略。
画出第0代龙曲线的字符串是FX。从下一代开始,按照如下方式利用前一代字符串进行字符替换,从而获得当前一代的龙曲线字符串。
X-> X+YF
Y-> FX+Y

根据上面的替换式,就有如下的1、2代龙曲线字符串。
第一代:FX+YF
第二代:FX+YF+FX-YF
我们想要求出第n代龙曲线字符串。不过,考虑到答案有可能很长,所以只想计算出第p个字符起始长度为l个字符的字符串。请编写程序实现这种功能。

输入
第一行输入测试用例的个数C(C<=50)。各测试用例的第一行分别输入3个整数,即龙曲线的世代n(0<=n<=50)、p以及l(1<=p<=1 000 000 000、1<=l<=50)。第n代龙曲线字符串的长度可假设成总是大于等于p+l的数值。
输出
每个测试用例在1行内输出第n代龙曲线字符串的第p个字符开始,输出l个字符。

示例输入
4
0 1 2
1 1 5
2 6 5
42 764853475 30
示例输出

FX
FY+YF
+FX-Y
FX-YF-FX+YF+FX-YF-FX+YF-FX-YF-

算法的详细设计思想:

分别找出字母和“+”“-”号规律,对其思想分别进行函数构造,最后进行整合,龙曲线字符串每一代都是前一代的前半部分,代数只决定了龙曲线字符串长度或者图形的终止位,但此次要求不输出图形只输出字符串规律,也就是说所有代数字符串长度内(例如第n代长度为3*2^n-1),相同位置规律是相同的。
  由题目可推得:
第一代:FX+YF
第二代:FX+YF+FX-YF
第三代:FX+YF+FX-YF+FX+YF-FX-YF
由上式可看出每一代都是下一代前半部分,还可推出两个规律,字母规律和正负号规律。
字母规律:每六个一循环,第一,二,四,五位分别为F,X,Y,F.
符号规律:符号位都是3的倍数,并且规律如下。
第一代                      +
第二代              +       +       -
第三代         +    +   -   +   +   -   -
                   1    2   3   4   5   6   7
由上式可看出,每代符号会继承上一代,并且在它们空隙处按照“+” “-”循环插入,类如,第三代继承第二代的2,4,6位置,在1,3,5,7按照“+”“-”循环插入。由此我们可以推算出在奇数位上1,3,5,7······上的奇数位是“+”,偶数位是“-”。例如7在奇数中排第四个为“-”。
      如果符号在偶数位,肯定继承自上一代,对其除2,算出上一代位置直到是奇数位为止,然后套用上述规律。
 源代码:
#include<iostream>
#include<math.h>
using namespace std;
int show(int q)//所选取片段中6位一循环,1,2,4,5位为F,X,Y,F.
{
    if(q%6==1||q%6==5) {cout<<"F";}
    if(q%6==2)         {cout<<"X";}
    if(q%6==4)         {cout<<"Y";}
}
int test(int y)//若符号在偶数除二,直到为奇数为止。
{
   if(y%2==1)
   return y;
   else test(y/2);
}
int show2(int x)//若此奇数在所有奇数中位置为偶数输出“-”,否则输出“+”。
{
    int a=test(x);
    if(((a+1)/2)%2==0)  {cout<<"-";}
    else              {cout<<"+";}
}
int main()
{
    int i,j,p,l,c,x,n;
    cin>>n;
    for(j=0;j<n;j++)
    {
      cin>>c>>p>>l;//输入世代c,起始位置p,长度l。
      if(p+l>3*pow(2,c)-1)//判断所求位置是否该代总长度。   
cout<<”error”<<endl; 
else
      for(i=p;i<p+l;i++)
      {
         show(i);//输出字母。
         if(i%3==0)//在3倍数位为“+” “-”号。
           {
            x=i/3;//对“+” “-”号单独排序。
            show2(x);//对“+” “-”号进行判断。
           }
      }
      cout<<""<<endl;
    }
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值