久 WA 必 AC。。。
知识点: 多边形重心、圆和线段的交、点到线段距离、点在线段的投影等基本知识。
Code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
#define FOR(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define DOR(i,a,b) for(int (i)=(a);(i)>=(b);(i)--)
#define oo 1e6
#define eps 1e-2
#define nMax 100000
#define pb push_back
#define dbg(x) cerr << __LINE__ << ": " << #x << " = " << x << endl
#define F first
#define S second
#define bug puts("OOOOh.....");
#define zero(x) (((x)>0?(x):-(x))<eps)
#define LL long long
#define DB double
#define sf scanf
#define pf printf
#define rep(i,n) for(int (i)=0;(i)<(n);(i)++)
double const pi = acos(-1.0);
double inline sqr(double x) { return x*x; }
int dcmp(double x){
if(fabs(x)<eps) return 0;
return x>0?1:-1;
}
// Describe of the 2_K Geomtry
// First Part : Point and Line
// First Part:
// ************************* Point and Line *******************************\\
class point {
public:
double x,y;
point (double x=0,double y=0):x(x),y(y) {}
void make(double _x,double _y) {x=_x;y=_y;}
void read() { scanf("%lf%lf",&x,&y); }
void out() { printf("%.2lf %.2lf\n",x,y);}
double len() { return sqrt(x*x+y*y); }
point friend operator - (point const& u,point const& v) {
return point(u.x-v.x,u.y-v.y);
}
point friend operator + (point const& u,point const& v) {
return point(u.x+v.x,u.y+v.y);
}
double friend operator * (point const& u,point const& v) {
return u.x*v.y-u.y*v.x;
}
double friend operator ^ (point const& u,point const& v) {
return u.x*v.x+u.y*v.y;
}
point friend operator * (point const& u,double const& k) {
return point(u.x*k,u.y*k);
}
point friend operator / (point const& u,double const& k) { return point(u.x/k,u.y/k); }
friend bool operator < (point const& u,point const& v){
if(dcmp(v.x-u.x)==0) return dcmp(u.y-v.y)<0;
return dcmp(u.x-v.x)<0;
}
friend bool operator != (point const& u,point const& v){
return dcmp(u.x-v.x) || dcmp(u.y-v.y);
}
point rotate(double s) {
return point(x*cos(s) + y*sin(s),\
-x*sin(s) + y*cos(s));
}
};
typedef class line{
public:
point a,b;
line() {}
line (point a,point b):a(a),b(b){}
void make(point u,point v) {a=u;b=v;}
void read() { a.read(),b.read(); }
}segment;
double det(point u,point v) {
return u.x*v.y - u.y*v.x;
}
double dot(point u,point v) {
return u.x*v.x + u.y*v.y;
}
// Weather P is On the Segment (uv)
int dot_on_seg(point p,point u,point v){
return dcmp(det(p-u,v-p))==0 && dcmp(dot(p-u,v-p)) >= 0; // '>=' means P is u or v
}
// The distance from point p to line l
double PToLine(point p,line l) {
return fabs((p-l.a)*(l.a-l.b))/(l.a-l.b).len();
}
// The ProJect Of Point(p) To Line(l)
point PointProjectLine(point p,line l) {
double t = dot(l.b-l.a,p-l.a)/dot(l.b-l.a,l.b-l.a);
return l.a + (l.b-l.a)*t;
}
// *********************** First Part end *****************************************\\
struct circle {
point O;
double r;
circle() {};
circle(point O,double r):O(O),r(r){};
};
// Sovle Part :
double len,T;
point p[10];
double const g = 981.0;
int cas = 1;
void check(point p,double r,line l,int &ans){
double d = PToLine(p,l);
if(dcmp(d-r)>0) return ;
point q = PointProjectLine(p,l);
if(dcmp(d-r)==0) {
if(dot_on_seg(q,l.a,l.b)) ans++;
return ;
}
double sita = (p-q).len()/r;
if(sita > 1) sita = 1;
sita = acos(sita);
point v = q-p;
v = v/v.len();
point s1 = v.rotate(sita)*r + p;
if(dot_on_seg(s1,l.a,l.b)) ans ++;
s1 = v.rotate(-sita)*r + p;
if(dot_on_seg(s1,l.a,l.b)) ans ++;
}
point Center(point a,point b,point c) {
return (a+b+c)/3.0;
}
point Centroid(point p[],int n){
point g(0,0);
point O(0,0);
p[n]=p[0];
double tmp = 0;
rep(i,n) {
g = g + Center(O,p[i],p[i+1])*det(p[i]-O,p[i+1]-O);
tmp += det(p[i]-O,p[i+1]-O);
}
g = g/tmp;
return g;
}
void work() {
double l = sqr(T) * g / 4.0 / sqr(pi);
l -= len;
// dbg(l);
if(dcmp(l) < 0) {
pf("Pendulum %d: No\n",cas++);
return ;
}
point g = Centroid(p,4);
p[4] = p[0];
int ans = 0;
rep(i,4) {
check(g,l,line(p[i],p[i+1]),ans);
}
rep(i,4) {
double d = (g-p[i]).len();
if(dcmp(d-l)==0) ans--;
}
if(ans == 0) {
pf("Pendulum %d: No\n",cas++);
}
else {
pf("Pendulum %d: Yes %d\n",cas++,ans);
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
while(~sf("%lf%lf",&len,&T)){
if(dcmp(len) <= 0) break;
rep(i,4) p[i].read();
work();
}
return 0;
}