计算几何类型,圆与三角形的距离 51Nod1298

1.首先,发现了一个错误点,那就是,经常容易忘了平方,比如说这个就是忘了平方,代码中会指出。

2.相信自己已经证明过的底层代码库,比如这里的那些abs,CHAJI之类的函数。

3.记得分解问题,分解问题是一个解决问题的方法,这正是我所追求的。

4.编写代码要分解问题,自顶向下,这样不容易出错,每一步都要仔细,距离一发AC不是梦。

5.点积的表示是投影和夹角(x1*x2+y1*y2) , 二维叉积表示的是垂直平面的向量和旋转的顺时针还是逆时针。(x1*y2-x2*y1)

6.这个是经常使用的函数,要保留代码,以后做项目可以使用。

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <map>
#include <vector>
#include <queue>
#include <algorithm>
#define FOR(i,s,e) for(int i=s;i<e;i++)
#define MEM(i,a) memset(i , a , sizeof(i))
#define DB double
using namespace std ;
const int maxEdge = 1000000 ;
const int maxNode = 1000 ;
const int INF = 0x3f3f3f3f;
int sco[maxNode] ;
int headEdge[maxNode] ;
struct node{
    int s,e,w ;
    int next ;
    void set_data(int ts,int te,int tw){
        s = ts , e = te , w = tw ; next = headEdge[s] ;
    }
}Edge[maxEdge] ;
int cntEdge = 0  ;
void add_Edge(int s,int e,int w){
    Edge[cntEdge].set_data(s,e,w) ;
    headEdge[s] = cntEdge ++ ;
}


int maxSco = 0;
int minTime = 0 ;
int dis[maxNode] ;
int maxsco[maxNode] ;
void init(){
    cntEdge = 0 ;
    memset(headEdge , -1 , sizeof(headEdge)) ;
    maxSco = 0 ; minTime = INF ;
    MEM(dis , INF) ;
    MEM(maxsco , 0) ;
}
int inQueue[maxNode] ;
#define PUSH(e) \
if(inQueue[e] == 0){\
    inQueue[e] = 1 ;\
    q.push(e) ;\
}
void SPFA(int s){
    MEM(inQueue , 0) ;
    queue <int> q ;
    q.push(s) ; inQueue[s] = 1 ; dis[s] = 0 ; maxsco[s] = sco[s] ;
    while(!q.empty()){
        int t = q.front() ;
        for(int i=headEdge[t];i!=-1;i=Edge[i].next){
            int e = Edge[i].e ; int w = Edge[i].w ;
            if(dis[t] + w < dis[e]) {
                dis[e] = dis[t] + w ;
                maxsco[e] = maxsco[t] + sco[e] ;
                PUSH(e) ;
            }
            else if(dis[t] + w == dis[e]){
                if(maxsco[t] + sco[e] > maxsco[e]) {
                    maxsco[e] = maxsco[t] + sco[e] ;
                    PUSH(e) ;
                }
            }
        }
        q.pop() ;
        inQueue[t] = 0 ;
    }
}
double cx , cy , cr ;
double x[3] , y[3] ;
int Getres(int res){
    return res == 0 || res == 2 ? 0 : 1 ;
}
double double_abs(double a){
    return a > 0 ? a : -a ;
}
int GetValue(double tmo){
    if(double_abs(tmo*tmo-cr*cr) <= 1e-7) return 100 ;
    else if(tmo < cr*cr) return 1 ;
    else if(tmo > cr*cr) return 0 ;
}
double PointDis(double x , double y){
    return (cx-x)*(cx-x)+(cy-y)*(cy-y) ;
}
int PointInside(double x , double y){
    return GetValue(PointDis(x,y)) ;
}
#include <math.h>
#define VX (x2-x1)
#define VY (y2-y1)
#define VCMOD (sqrt((VX*VX+VY*VY)))
double CHAJI(double x1 , double y1,double x2 ,double y2){
    return x1 * x2 + y2 * y1 ;
}
double GetMin(double x1 , double y1,double x2 ,double y2){
    return double_abs(CHAJI(x1-cx,y1-cy,VY/VCMOD,-VX/VCMOD)) ;
}
int InSide(double x1,double y1,double x2,double y2){
    double r = CHAJI(x1-cx , y1-cy , VX , VY) * CHAJI(x2-cx,y2-cy,VX,VY) ;
    if(r > 0) return 0 ;
    else return 1 ;
}
int JudgeLine(double x1, double y1 , double x2 ,double y2){
    if(InSide(x1 , y1 , x2 , y2)){
        //printf("inside\n") ;
        double tmo = GetMin(x1 , y1 , x2 , y2) ;
        int res = GetValue(tmo*tmo) ; ///这个地方原来没有平方,所以除了问题,这个是最骚的,所以以后一定注意,不要有低级错误,坚持慢走但是步步为营。
        res += GetValue(max(PointDis(x1 , y1) , PointDis(x2 , y2))) ;
        return Getres(res) ;
    }
    else {
        //printf("notInside\n");
        int res = PointInside(x1 , y1) + PointInside(x2 , y2) ;
        return Getres(res) ;
    }
}
int Judge(){
    if(JudgeLine(x[0] , y[0] , x[1] , y[1]) == 1) return 1 ;
    if(JudgeLine(x[0] , y[0] , x[2] , y[2]) == 1) return 1 ;
    if(JudgeLine(x[1] , y[1] , x[2] , y[2]) == 1) return 1 ;
    return 0 ;
}
int main(){
    int T ; cin >> T ;
    while(T --){
    cin >> cx >> cy >> cr ;
    for(int i=0;i<3;i++){
        cin >> x[i] >> y[i] ;
    }
    int res = Judge() ;
    if(res == 1){
        printf("Yes\n") ;
    }
    else printf("No\n") ;
    }
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值