UVa 11189 A Simple Pendulum

Link To The Problem


久 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;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值