Rotational Painting
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2378 Accepted Submission(s): 672
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 x
i and y
i representing a point of the polygon. (x
i, y
i) to (x
i+1, y
i+1) represents a edge of the polygon (1<=i<n), and (x
n,y
n) to (x
1, y
1) 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
Hint
The sample test cases can be demonstrated by Figure 1 and Figure 2 in Description part.
Source
2010 Asia Hangzhou Regional Contest
题目所求,给一个多边形,问有多少种可以将多边形放稳的方法。先求出重心,看重心映射到凸包的每两条边上,在线段上说明可以放。详见代码。
题目地址:Rotational Painting
AC代码:
#include<iostream>
#include<string>
#include<cstring>
#include<vector>
#include<iomanip>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<deque>
#include<cstdio>
using namespace std;
double eps=1e-8;
const int N=50005;
struct point
{
double x,y;
} p[N],res[N],q[N];
bool mult(point sp,point ep,point op)
{
return (sp.x-op.x)*(ep.y-op.y)>=(ep.x-op.x)*(sp.y-op.y);
} //返回凸包上顶点的个数,不包括在凸包上的点
bool operator < (const point &l,const point &r)
{
return l.y<r.y||(l.y==r.y&&l.x<r.x);
}
int tubao(point pnt[], int n)
{
int i, len, top = 1;
sort(pnt, pnt + n);
if(n == 0) return 0;
res[0] = pnt[0];
if(n == 1) return 1;
res[1] = pnt[1];
if(n == 2) return 2;
res[2] = pnt[2];
for(i = 2; i < n; i ++)
{
while(top && mult(pnt[i], res[top], res[top-1])) top --;
res[++top] = pnt[i];
}
len = top;
res[++top] = pnt[n - 2];
for(i = n - 3; i >= 0; i --)
{
while(top != len && mult(pnt[i], res[top], res[top-1]))
top --;
res[++top] = pnt[i];
}
return top;
}
bool dianmul(point a,point b,point c) //c向ab线段作垂足落在ab上
{
double x1,y1,x2,y2,x3,y3,x4,y4;
x1=b.x-a.x,y1=b.y-a.y;
x2=c.x-a.x,y2=c.y-a.y;
x3=a.x-b.x,y3=a.y-b.y;
x4=c.x-b.x,y4=c.y-b.y;
if(x1*x2+y1*y2>eps&&x3*x4+y3*y4>eps) return true;
return false;
}
point gravi(point p[],int n) //求重心
{
int i;
double A=0, a;
point t;
t.x = t.y = 0;
p[n] = p[0];
for (i=0; i < n; i++)
{
a = p[i].x*p[i+1].y - p[i+1].x*p[i].y;
t.x += (p[i].x + p[i+1].x) * a;
t.y += (p[i].y + p[i+1].y) * a;
A += a;
}
t.x /= A*3;
t.y /= A*3;
return t;
}
int main()
{
int i,n,tes;
point zhong; //重心的坐标
cin>>tes;
while(tes--)
{
cin>>n;
for(i=0; i<n; i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
zhong=gravi(p,n);
int len=tubao(p,n);
res[len]=res[0];
int cnt=0;
for(i=0; i<len; i++)
{
if(dianmul(res[i],res[i+1],zhong))
{
cnt++;
}
}
cout<<cnt<<endl;
}
return 0;
}
//203MS