龙曲线介绍:
龙曲线是以简单的数学规则画出一种曲线,它具有以下形态。曲线从一个简单的线段起始,按照一定规则变换此线段完成整个曲线。每形成一次变换称为“完成了一次变换代”,而每完成一代,曲线会进化到更复杂的形式。像这种“放大其一小部分的形状时,表现出与整个形状极为相似构造的图形”,就是分形。
画出龙曲线的方法暂且就称为龙曲线字符串吧!龙曲线字符串由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;
}
}