An Easy Physics Problem

41 篇文章 0 订阅
16 篇文章 0 订阅

An Easy Physics Problem

这里写图片描述
.
.
题意:平面上一个点与圆,点延一个方向前进,问能否达到另外一个点。
.
.
解法:分两种,1是相撞,2是相离或相切。对于第二种直接求解就好了,而第一种注意一下精度,考虑点出现在相撞前的地方等就好了。
.
.
队友代码

#include <cstdio>
#include <iostream>
#include <cmath>
#include <vector>

using namespace std;

const double eps=1e-6;
typedef long long LL;

int dcmp(double x) {
    if (fabs(x)<eps) return 0;
    else if (x<0) return -1;
    else return 1;
}

struct Point {
    double x, y;
    Point() {}
    Point(double x, double y): x(x), y(y) {}
    void read() {scanf("%lf%lf", &x, &y);}
    Point operator+ (const Point& a) {
        return Point(x+a.x, y+a.y);
    }
    Point operator- (const Point& a) {
        return Point(x-a.x, y-a.y);
    }
} a, v, b;

Point operator*(double t, Point a) {
    return Point(t*a.x, t*a.y);
}
struct Line {
    Point p, v;
    Line() {}
    Line(Point p, Point v): p(p.x, p.y), v(v.x, v.y) {}
    Point point(double t) {
        return p+(t*v);
    }
};
struct Circle {
    Point c;
    double r;
    void read() {c.read(); scanf("%lf", &r);}
} cc;

inline double sqr(double x) {return x*x;}
int getLineCircleIntersection(Line L, Circle C, Point& sol) {
    double t;
    double a=L.v.x, b=L.p.x-C.c.x, c=L.v.y, d=L.p.y-C.c.y;
    double e=sqr(a)+sqr(c), f=2*(a*b+c*d), g=sqr(b)+sqr(d)-sqr(C.r);
    double delta=f*f-4*e*g;
    if (dcmp(delta)<=0) return 0;
    else {
        t=(-f-sqrt(delta))/(2*e);
        if (dcmp(t)>0) {
            sol=L.point(t);
            return 1;
        }
        else return 0;
    }
}

bool det(Point a, Point b) {
    return fabs(a.x*b.y-a.y*b.x)<eps;
}

bool SameLine(Point v, Point p) {
    double a=v.x, b=v.y, c=p.x, d=p.y;
        int aa=dcmp(a), bb=dcmp(b);
        int cc=dcmp(c), dd=dcmp(d);
        if (aa*cc>=0&&bb*dd>=0&&det(v, p)) return true;
        else return false;
}

double dist(Point a, Point b) {
    return hypot(a.x-b.x, a.y-b.y);
}
double Dot(Point a, Point b) {
    return a.x*b.x+a.y*b.y;
}
Point GetLineProjection(Point P, Point A, Point B) {
    Point v=B-A;
    return A+(Dot(v, P-A)/Dot(v, v))*v;
}

int main() {
    // freopen("untitled.in", "r", stdin);
    int T, kase=0; cin >> T;
    while (T--) {
        printf("Case #%d: ", ++kase);
        cc.read(); a.read(); v.read(); b.read();
        Line l(a, v);
        Point i;
        bool flag=getLineCircleIntersection(l, cc, i);
        if (flag) {
            if (SameLine(v, b-a)&&dist(a, b)<dist(a, i)+eps) puts("Yes");
            else {
                Point bb=GetLineProjection(b, i, cc.c);
                b=2*bb-b;
                if (SameLine(Point(-v.x, -v.y), b-i)) puts("Yes");
                else puts("No");
            }
        }
        else {
            if (SameLine(v, b-a)) puts("Yes");
            else puts("No");
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
easyswoole是一个基于Swoole扩展的PHP框架,它提供了一种简单且高效的方式来构建WebSocket应用程序。WebSocket是一种在Web浏览器和服务器之间进行全双工通信的协议,它允许服务器主动向客户端推送数据,而不需要客户端发起请求。 使用easyswoole可以轻松地创建和管理WebSocket服务器,并处理来自客户端的连接、消息和事件。下面是一个简单的示例代码,演示了如何使用easyswoole创建一个WebSocket服务器: ```php <?php use EasySwoole\EasySwoole\ServerManager; use EasySwoole\EasySwoole\Swoole\EventRegister; use EasySwoole\EasySwoole\AbstractInterface\Event; use Swoole\WebSocket\Frame; use Swoole\WebSocket\Server; // 注册WebSocket事件回调 Event::getInstance()->set(EventRegister::onMessage, function (Server $server, Frame $frame) { // 处理收到的消息 $data = $frame->data; // TODO: 处理消息逻辑 // 向客户端发送消息 $server->push($frame->fd, 'Hello, client!'); }); // 创建WebSocket服务器 $server = ServerManager::getInstance()->getSwooleServer(); $server->on('WorkerStart', function () { echo "WebSocket server started\n"; }); // 启动服务器 EasySwoole\EasySwoole\Core::getInstance()->initialize(); ``` 上述代码中,我们首先注册了一个`onMessage`事件回调函数,用于处理收到的消息。在这个示例中,我们简单地向客户端发送了一条回复消息。然后,我们创建了一个WebSocket服务器,并在`WorkerStart`事件回调中输出了一条启动消息。最后,我们使用`EasySwoole\EasySwoole\Core::getInstance()->initialize()`启动了服务器。 请注意,上述代码只是一个简单的示例,实际应用中可能需要更复杂的逻辑来处理不同的消息和事件。你可以根据自己的需求进行扩展和定制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值