10609 - Fractal (模拟,dfs)

Problem A
Fractal
Input: 
Standard Input

Output: Standard Output

Time Limit: 3 Seconds

 

A fractal is a rough or fragmented geometric shape that can be subdivided in parts, each of which is (at least approximately) a smaller copy of the whole. Fractals are generally self-similar (bits look like the whole) and independent of scale (they look similar, no matter how close you zoom in).

 

Below you can see picture of a well-known fractal. Actually this picture shows the steps of the making of a fractal:

 

 

In this problem you will have to draw a fractal very similar to the one above. The fractal that you have to work with is given below:

In real life it is impossible to draw a fractal exactly according to its definition because somewhere we must stop drawing it. For example in the picture above we have stopped drawing when the length of the line on which a triangle has to be drawn is less than five.

 

Now let us discuss in detail how the fractal is to be drawn. You will be given the coordinates of A (x1, y1) and B (x2, y2). In the figure above the coordinate of A is (-300, -100) and the coordinate of B is (300, -200). C and D are the points, which divides AB in ratio 1:3 and 3:1. So now you have to draw an equilateral triangle CED based on CD, of course the base is erased. And then you find two points, which divide CE in the ratio 1:3 and 3:1. The same thing applies for ED and this process continues recursively up to the point when the length of the side of drawn equilateral triangles is less than a certain value T. Now if you look at the picture above you will find that it has two terminal points A and B and many corner points like C, E and D. Your job is to find the coordinates of these terminal points and corner points and print them in a certain order.

 

 

Input 

The input file contains less than 10 lines of input.

 

Each line contains five numbers. The first four numbers are the coordinates x1,y1, x2, y2 (-10000<x1,y1,x2,y2<10000) and the last numberT(1<T<1000) is the terminating threshold value. I mean when the line to be drawn will be less than T drawing will stop. The value of T will be such that the length of the line to be drawn will never be equal to T.

 

Input is terminated by a case whose value of T is less than 1. This case should not be processed.

 

Output 

For each line of input you should output S+2 lines of outputs. The first line is the serial no of the output as shown in the sample output. Next line contains the number S, where S is the number of vertex and terminal points in the drawn fractal. Each of the S lines after that contains two floating-point numbers indicating the coordinate of one terminal point or vertex. The terminal points should be sorted in increasing order of the value of abscissa of the coordinate. In case of a tie the points should be sorted in ascending order of the ordinate. Two values are considered same if they differ by a value less than 1e-8. All printed floating point numbers have five digits after the decimal point. Errors less than 2*10-5will be tolerated.

 

Sample Input                           Output for Sample Input

10 10 -10 -10 5.1
-10 -10 10 10 5.1
5 5 -5 -8 .3

Case 1:

11

-10.00000 -10.00000

-5.00000 -5.00000

-1.58494 -5.91506

0.24519 -12.74519

5.00000 5.00000

5.24519 -7.74519

5.91506 1.58494

7.74519 -5.24519

8.66025 -8.66025

10.00000 10.00000

12.74519 -0.24519

Case 2:

11

-12.74519 0.24519

-10.00000 -10.00000

-8.66025 8.66025

-7.74519 5.24519

-5.91506 -1.58494

-5.24519 7.74519

-5.00000 -5.00000

-0.24519 12.74519

1.58494 5.91506

5.00000 5.00000

10.00000 10.00000

 

题意:题意转自 http://blog.csdn.net/keshuai19940722/article/details/19977387

给出A,B两个点的坐标,以及T,每次找到A、B的四等分点C,D,然后以AB/2为边长,C,D为顶点,构建一个等边三角形,E为另外一个顶点,然后再对C,E;E,D做同样的操作,直到构建的等边三角形的边长小于T时。输出所有过程中的点,按照x坐标排序,相同的按照y坐标。

思路:先求出2个四分之一点,这步容易解决,然后根据向量旋转的方法,求出向外那点的坐标即可。dfs去模拟这个过程,在过程中把点都记录下来。

代码:

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;
const int MAXN = 100005;
const double pi = acos(-1.0);
int ansn;
double Ax, Ay, Bx, By, T;
struct Point {
	double x, y;
	Point() {}
	Point(double xx, double yy) {x = xx; y = yy;}
} ans[MAXN];

bool cmp(Point a, Point b) {
	if (fabs(a.x - b.x) > 1e-6)
		return a.x < b.x;
	return a.y < b.y;
}

double dis(Point A, Point B) {
	return sqrt((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y));
}

void dfs(Point A, Point B) {
	if (dis(A, B) / 2 < T) return;
	Point mid((A.x + B.x) / 2, (A.y + B.y) / 2);
	Point Amid((A.x + mid.x) / 2, (A.y + mid.y) / 2);
	Point Bmid((mid.x + B.x) / 2, (mid.y + B.y) / 2);
	Point C(cos(pi / 3) * (Bmid.x - Amid.x) - sin(pi / 3) * (Bmid.y - Amid.y) + Amid.x, sin(pi / 3) * (Bmid.x - Amid.x) + cos(pi / 3) * (Bmid.y - Amid.y) + Amid.y);
	ans[ansn++] = Amid; ans[ansn++] = Bmid; ans[ansn++] = C;
	dfs(Amid, C);
	dfs(C, Bmid);
}

void solve() {
	ansn = 0;
	Point A = Point(Ax, Ay); Point B = Point(Bx, By);
	ans[ansn++] = A; ans[ansn++] = B;
	dfs(A, B);
	sort(ans, ans + ansn, cmp);
	printf("%d\n", ansn);
	for (int i = 0; i < ansn; i++)
		printf("%.5lf %.5lf\n", ans[i].x, ans[i].y);
}

int main() {
	int cas = 0;
	while (~scanf("%lf%lf%lf%lf%lf", &Ax, &Ay, &Bx, &By, &T) && T >= 1) {
		printf("Case %d:\n", ++cas);
		solve();
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值