1. 程式人生 > >BZOJ 1719--[Usaco2006 Jan] Roping the Field 麥田巨畫

BZOJ 1719--[Usaco2006 Jan] Roping the Field 麥田巨畫

表示 string rain discuss 處理 要求 tween fine output

1719: [Usaco2006 Jan] Roping the Field 麥田巨畫

Time Limit: 5 Sec Memory Limit: 64 MB
Submit: 82 Solved: 26
[Submit][Status][Discuss]

Description

Farmer John is quite the nature artist: he often constructs large works of art on his farm. Today, FJ wants to construct a giant "field web". FJ‘s field is large convex polygon with fences along the boundary and fence posts at each of the N corners (1 <= N <= 150). To construct his field web, FJ wants to run as many ropes as possible in straight lines between pairs of non-adjacent fence posts such that no two ropes cross. There is one complication: FJ‘s field is not completely usable. Some evil aliens have created a total of G (0 <= G <= 100) grain circles in the field, all of radius R (1 <= R <= 100,000). FJ is afraid to upset the aliens, and therefore doesn‘t want the ropes to pass through, or even touch the very edge of a grain circle. Note that although the centers of all the circles are contained within the field, a wide radius may make it extend outside of the field, and both fences and fence posts may be within a grain circle. Given the locations of the fence posts and the centers of the circles, determine the maximum number of ropes that FJ can use to create his field web. FJ‘s fence posts and the circle centers all have integer coordinates X and Y each of which is in the range 0..1,000,000.

約翰真是一個自然派藝術大師,他常常在他的田地上創作一些巨大的藝術傑作.今天,他想在麥田上創作一幅由繩索構成的巨畫.他的麥田是一個多邊形,由N(1≤N≤150)個籬笆樁和之間的籬笆圍成.為了創作他的巨畫,他打算用盡量多的數量的繩索,筆直地連接兩個不相鄰的籬笆樁.但是為了畫作的優美,任意兩根繩索不得交叉. 約翰有一個難處:一些邪惡的外星人在他的麥田上整出了G(O≤G≤100)個怪圈.這些怪圈都有一定的半徑R(1≤R≤100000).他不敢惹外星人,所以不想有任何繩索通過這些怪圈,即使碰到怪圈的邊際也不行.這些怪圈的圓心都在麥田之內,但一些怪圈可能有部分在麥田之外.一些籬笆或者籬笆樁都有可能在某一個怪圈裏. 給出籬笆樁和怪圈的坐標,計算最多的繩索數.所有的坐標都是[0,10^61內的整數.

Input

* Line 1: Three space-separated integers: N, G, and R * Lines 2..N+1: Each line contains two space-separated integers that are the X,Y position of a fence post on the boundary of FJ‘s field. * Lines N+2..N+G+1: Each line contains two space-separated integers that are the X,Y position of a circle‘s center inside FJ‘s field.

第1行輸入三個整數N,G,R.接下來N行每行輸入兩個整數表示籬笆樁的坐標.接下來G行每行輸入兩個整數表示一個怪圈的圓心坐標.

Output

* Line 1: A single integer that is the largest number of ropes FJ can use for his artistic creation.

最多的線索數.

Sample Input

5 3 1
6 10
10 7
9 1
2 0
0 3
2 2
5 6
8 3

INPUT DETAILS:

A pentagonal field, in which all possible ropes are blocked by three
grain circles, except for the rope between fenceposts 2 and 4.

Sample Output

1

HINT

除了籬笆樁2和4之間可以連接繩索,其余均會經過怪圈

題目鏈接:

    http://www.lydsy.com/JudgeOnline/problem.php?id=1719

Solution

  首先看到題目應該是幾何題無誤(假裝很有道理
  看到n<=150感覺似乎暴力也能過。。想想邊數最多也只有22500條。。。
  於是這時候應該馬上想到先預處理每條邊是否可以連。。。
  直接算圓和線段的交點?感覺應該可以但是似乎不怎麽好寫。。。
  考慮題意。。只要線段有部分含於圓內就不能連。。而這個“部分”可以直接認為是線段上與圓心最近的點。。
  於是這個預處理就轉化成了求點到線段的最小距離。。這個套套公式就好。。感覺三分也可以但是tle了(可能是我寫炸了。。
  預處理完之後,考慮怎麽求答案。。。
  要求線段之間不可以相交。。。。
  說白了就是不能有1->4 , 2->5這樣的線段同時存在。。考慮DP。。那肯定只能區間DP了。。
  n<=150的話O(n^3)還是很輕松的吧

代碼

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<queue>
#include<vector>
#include<map>
#define N 20050
#define ept 1e-6
using namespace std;
int n,m;
double R;
struct P{
	double x,y;
}a[200],b[200];
int f[200][200];
bool vis[200][200];
double dis(P u,P v){
	return sqrt((u.x-v.x)*(u.x-v.x)+(u.y-v.y)*(u.y-v.y));
}
double DIS(P u,P v,P w) {  
    double space=0;  
    double a,b,c;  
    a=dis(u,v);
    b=dis(u,w);  
    c=dis(v,w);
    if(c<=ept||b<=ept) {  
        space=0;  
        return space;  
    }  
    if(a<=ept){  
        space=b;  
        return space;  
    }  
    if(c*c>=a*a+b*b){  
        space=b;  
        return space;  
    }  
    if(b*b>=a*a+c*c) {  
        space=c;  
        return space;  
    }  
    double p=(a+b+c)/2;
    double s=sqrt(p*(p-a)*(p-b)*(p-c));
    space=2*s/a; 
    return space;
}
bool judge(P u,P v,P w){
	double d1=DIS(u,v,w);
	if(d1>R) return 0;
	return 1;
}
bool check(P u,P v){
	for(int i=1;i<=m;i++)
		if(judge(u,v,b[i])) return 0;
	return 1;
}
int main(){
	scanf("%d%d%lf",&n,&m,&R);
	for(int i=1;i<=n;i++)
		scanf("%lf%lf",&a[i].x,&a[i].y);
	for(int i=1;i<=m;i++)
		scanf("%lf%lf",&b[i].x,&b[i].y);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(i==j) continue;
			vis[i][j]=check(a[i],a[j]);
		}
	}
	for(int len=3;len<=n;len++){
		for(int i=1;i<=n-len+1;i++){
			for(int j=i;j<=i+len-1;j++)
				f[i][i+len-1]=max(f[i][i+len-1],f[i][j]+f[j][i+len-1]);
			if(vis[i][i+len-1]&&(i!=1||i+len-1!=n))
				f[i][i+len-1]++;
		}
	}
	printf("%d\n",f[1][n]);
	return 0;
}

  

  

This passage is made by Iscream-2001.

BZOJ 1719--[Usaco2006 Jan] Roping the Field 麥田巨畫