topcoder SRM500 DIV1 level2 500分

Problem Statement

 Nick likes to draw fractals. For the special occasion of Single Round Match 500, he decided to draw the 500th generation of his favorite fractal.

Each generation of the fractal can be described as a set of segments on the plane. Some of these segments are calledfinal and all other are considered to be non-final. In each non-final segment, one of its endpoints is chosen and called theroot of this segment. In pictures below, solid and dotted lines are used to represent final and non-final segments, correspondingly.

The first generation consists of one segment with endpoints (0, 0) and (0, 81). This segment is non-final and its root is (0, 0).



The i-th generation, i >= 2, is produced from the (i-1)-th generation as follows. All final segments from the (i-1)-th generation are included into the i-th generation without any changes. For each non-final segment from the (i-1)-th generation, let A and B be its endpoints, with A being its root. The following steps are then done:
  • The point C is drawn on the segment AB so that the length of segment AC is twice as large as the length of segment BC.
  • Segment CD is drawn as the rotation of segment CB around point C by 90 degrees clockwise.
  • Segment CE is drawn as the rotation of segment CB around point C by 90 degress counter-clockwise.
  • Segment AC is included in the i-th generation as a final segment.
  • Segments CB, CD and CE are included in the i-th generation as non-final segments. The root of each of these three segments is point C.
The second and third generations of this fractal are shown on the picture below.

 

Consider a rectangle R on the plane that consists of points (x, y), such that x1 <= x <= x2 and y1 <= y <= y2. Let S be the set of all segments of the 500-th generation of the fractal described above (both final and non-final ones). Return the total length of all parts of segments from S that belong to rectangle R.

Definition

 
Class:FractalPicture
Method:getLength
Parameters:int, int, int, int
Returns:double
Method signature:double getLength(int x1, int y1, int x2, int y2)
(be sure your method is public)
 
 

Notes

-The returned value must have an absolute or relative error less than 1e-9.

Constraints

-x1 will be between -100 and 100, inclusive.
-x2 will be between x1+1 and 100, inclusive.
-y1 will be between -100 and 100, inclusive.
-y2 will be between y1+1 and 100, inclusive.

Examples

0) 
 
-1
0
1
53
Returns: 53.0
Only one part of fractal segments belongs to this rectangle: (0, 0) - (0, 53).
1) 
 
1
1
10
10
Returns: 0.0
No parts of fractal segments belong to this rectangle.
2) 
 
-10
54
10
55
Returns: 21.0
Two parts of fractal segments belong to this rectangle: (-10, 54) - (10, 54) and (0, 54) - (0, 55). Note that parts that lie on the rectangle's border also belong to the rectangle.
3) 
 
14
45
22
54
Returns: 2999.0

【题解】

我的思路和官方思路不一样。官方思路基于的是矩形切割,分治(貌似)

我的思路是将每个方格包含多少长度统计出来,最后输出答案。

离散化即可(包括点、线段)

【代码】

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>

using namespace std;

double s[505][505];

class FractalPicture
{
public:
	double getLength(int, int, int, int);
};

int get(int x)
{
    return (x+100)*2;
}

int get(int x,int y)
{
    return (min(x,y)+100)*2+1;
}

int dir(int x1,int y1,int x2,int y2)
{
    return x1==x2;
}

void work(int gg,int x1,int y1,int x2,int y2)
{
    int i,len,x,y;
    if (gg>500) return;
    len=abs(x1-x2)+abs(y1-y2);
    if (len>1)
    {
        int l=len/3;
        x=(x1+2*x2)/3;
        y=(y1+2*y2)/3;
        if (dir(x1,y1,x2,y2)==0)
        {
            int ll=min(x1,x),rr=max(x1,x);
            for (i=ll;i<rr;i++)
                s[get(i,i+1)][get(y1)]+=1;
            work(gg+1,x,y,x,y-l);
            work(gg+1,x,y,x,y+l);
        }
        else
        {
            int ll=min(y1,y),rr=max(y1,y);
            for (i=ll;i<rr;i++)
                s[get(x1)][get(i,i+1)]+=1;
            work(gg+1,x,y,x-l,y);
            work(gg+1,x,y,x+l,y);
        }
        work(gg+1,x,y,x2,y2);
    }
    else
    {
        if (dir(x1,y1,x2,y2)==0)
        {
            s[get(x1,x2)][get(y1)]+=1;
            s[get(x1,x2)][get(y1)-1]+=double(500-gg)/3;
            s[get(x1,x2)][get(y1)+1]+=double(500-gg)/3;
        }
        else
        {
            s[get(x1)][get(y1,y2)]+=1;
            s[get(x1)-1][get(y1,y2)]+=double(500-gg)/3;
            s[get(x1)+1][get(y1,y2)]+=double(500-gg)/3;
        }
        return;
    }
}

double FractalPicture::getLength(int x1, int y1, int x2, int y2)
{
	work(1,0,0,0,81);
	double ans=0;
	int i,j;
	for (i=x1;i<x2;i++)
        for (j=y1;j<y2;j++)
        {
            ans+=s[get(i,i+1)][get(j)];
            ans+=s[get(i)][get(j,j+1)];
            ans+=s[get(i,i+1)][get(j,j+1)];
        }
    for (i=x1;i<x2;i++)
        ans+=s[get(i,i+1)][get(y2)];
    for (i=y1;i<y2;i++)
        ans+=s[get(x2)][get(i,i+1)];
    return ans;
}
//以下的正式比赛是用不上。
int main()
{
    int x1,y1,x2,y2;
    cin >> x1 >> y1 >> x2 >> y2;
    FractalPicture a;
    cout << a.getLength(x1,y1,x2,y2);
}

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值