您的位置:首页 > 大数据 > 人工智能

HDU 3685 Rotational Painting

2015-10-25 10:10 621 查看
Problem Description

Josh Lyman is a gifted painter. One of his great works is a glass painting. He creates some well-designed lines on one side of a thick and polygonal glass, and renders it by some special dyes. The most fantastic thing is that it can generate different meaningful
paintings by rotating the glass. This method of design is called “Rotational Painting (RP)” which is created by Josh himself. 

You are a fan of Josh and you bought this glass at the astronomical sum of money. Since the glass is thick enough to put erectly on the table, you want to know in total how many ways you can put it so that you can enjoy as many as possible different paintings
hiding on the glass. We assume that material of the glass is uniformly distributed. If you can put it erectly and stably in any ways on the table, you can enjoy it. 

More specifically, if the polygonal glass is like the polygon in Figure 1, you have just two ways to put it on the table, since all the other ways are not stable. However, the glass like the polygon in Figure 2 has three ways to be appreciated. 



Pay attention to the cases in Figure 3. We consider that those glasses are not stable.



 

Input

The input file contains several test cases. The first line of the file contains an integer T representing the number of test cases. 

For each test case, the first line is an integer n representing the number of lines of the polygon. (3<=n<=50000). Then n lines follow. The ith line contains two real number xi and yi representing a point of the polygon. (xi,
yi) to (xi+1, yi+1) represents a edge of the polygon (1<=i<n), and (xn,yn) to (x1, y1) also represents a edge of the polygon. The input data insures that the polygon is not self-crossed.

 

Output

For each test case, output a single integer number in a line representing the number of ways to put the polygonal glass stably on the table.

 

Sample Input

2
4
0 0
100 0
99 1
1 1
6
0 0
0 10
1 10
1 1
10 1
10 0

 

Sample Output

2
3
HintThe sample test cases can be demonstrated by Figure 1 and Figure 2 in Description part.

 

Source

2010 Asia Hangzhou Regional Contest

 

求重心后求凸包,然后判断重心是否在每条边的范围内,如果是就加1.

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;

const int MAXN=100010;
const double ZERO=1e-8;

struct node
{
double x,y;
}q[MAXN],p[MAXN];
int N,M;

void Init()
{
scanf("%d",&N);
for (int i=0;i<N;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
}

double det(node a,node b,node c)
{
return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
}

double dot(node a,node b,node c)
{
return (b.x-a.x)*(c.x-a.x)+(b.y-a.y)*(c.y-a.y);
}

double det3(node a,node b,node c)
{
double s=det(a,b,c);
if (fabs(s)<=ZERO) return 0;
if (s<0) return -1; else return 1;
}

void Graham_scan(node *c,int &M0,int base,node q)
{
while (M0>base && det3(c[M0-2],c[M0-1],q)<=0) --M0;
c[M0]=q;
++M0;
}

bool cmp(node a,node b)
{
if ((a.y<b.y) || (a.y==b.y && a.x<b.x)) return 1; else return 0;
}

node c[MAXN];
void Graham(node *p,int N0,node *q,int &M0)
{
for (int i=0;i<=N0;++i) q[i]=p[i];
sort(q,q+N0,cmp);
M0=0;
for (int i=0;i<N0;++i)
Graham_scan(c,M0,1,q[i]);
int M1=M0;
for (int i=N0-1;i>=0;--i)
Graham_scan(c,M0,M1,q[i]);
for (int i=0;i<M0;++i)
q[i]=c[i];
}

int Find(node a,node b,node c)
{
double s=dot(b,a,c);
if (s>ZERO) return 0; else return 1;
}

bool Cleck(node a,node b,node c)
{
return ((!Find(a,b,c))&&(!Find(a,c,b)));
}

void Solve()
{
node o,o1;
double s=0,s1;
o.x=o.y=0;
for (int i=1;i<N-1;++i)
{
o1.x=(p[0].x+p[i].x+p[i+1].x)/3;
o1.y=(p[0].y+p[i].y+p[i+1].y)/3;
s1=det(p[0],p[i],p[i+1]);
s+=s1;
o.x+=o1.x*s1;
o.y+=o1.y*s1;
}
o.x/=s;
o.y/=s;
Graham(p,N,q,M);
q[M]=q[0];
int ans=0;
for (int i=0;i<M;++i)
if (Cleck(o,q[i],q[i+1])) ++ans;
printf("%d\n",ans);
}

int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int test;
scanf("%d",&test);
while (test--)
{
Init();
Solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACM算法