• 101992 I


    傻逼题,1000个点问你面积在[L,R]内的直角三角形有多少个

    好像大家都用的gcd,甚至atan2什么的。。。

    不过我受到去年北京J的毒害,全程用的整形。

    枚举顶点,极角排序,双指针扫一下,然后对每个存一下这个区间[l,r],就是这个区间里的和它能组成直角三角形

    然后在区间里二分判断面积就行

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 typedef long long db;
      4 int sign(db k){
      5     if (k>0) return 1; else if (k<0) return -1; return 0;
      6 }
      7 int cmp(db k1,db k2){return sign(k1-k2);}
      8 struct point{
      9     db x,y;
     10     point operator + (const point &k1) const{return (point){k1.x+x,k1.y+y};}
     11     point operator - (const point &k1) const{return (point){x-k1.x,y-k1.y};}
     12     point operator * (db k1) const{return (point){x*k1,y*k1};}
     13     point operator / (db k1) const{return (point){x/k1,y/k1};}
     14     db abs2(){return x*x+y*y;}
     15     int getP() const{return sign(y)==1||(sign(y)==0&&sign(x)==-1);}
     16 };
     17 db cross(point k1,point k2){return k1.x*k2.y-k1.y*k2.x;}
     18 db dot(point k1,point k2){return k1.x*k2.x+k1.y*k2.y;}
     19 int compareangle (point k1,point k2){//极角排序+&长度排序
     20     if(k1.getP()==k2.getP()){
     21         if(sign(cross(k1,k2))==0){
     22             return k1.abs2()<k2.abs2();
     23         }
     24         return sign(cross(k1,k2))>0;
     25     }
     26     return k1.getP()<k2.getP();
     27 }
     28 int t,n;db L,R;
     29 point p[1005];
     30 vector<point> v;
     31 vector<pair<int,int>>g[1005];
     32 int slove(int id){
     33     int res = 0;
     34     v.clear();
     35     for(int i=0;i<=n;i++)g[i].clear();
     36     for(int i=1;i<=n;i++){
     37         if(i==id)continue;
     38         v.push_back(p[i]-p[id]);
     39     }
     40     sort(v.begin(),v.end(),compareangle);
     41     int m = v.size();
     42     for(int i=0;i<m;i++)v.push_back(v[i]);
     43     int l=0,r=0;//
     44     for(int i=0;i<m;i++){
     45         l=max(l,i);
     46         point _90 = {-v[i].y,v[i].x};
     47         while (l+1<i+m&&cross(v[l+1],_90)>0&&cross(v[i],v[l+1])>=0)l++;//l+1>=90
     48         if(l+1<i+m&&cross(v[l+1],_90)==0&&dot(v[l+1],_90)>0){
     49             r = max(r,l+1);
     50             while (r+1<i+m&&cross(v[r+1],_90)==0&&cross(v[r+1],v[i])<=0)r++;
     51             g[i].push_back(make_pair(l+1,r));//[l+1,r]是直角
     52         }
     53     }
     54     for(int i=0;i<m;i++){
     55         if(g[i].empty())continue;
     56         int id1,id2;
     57         l = g[i][0].first,r = g[i][0].second;
     58         while (l<=r){
     59             int mid = l+r>>1;
     60             if(cross(v[i],v[mid])>=L*2)r=mid-1;
     61             else l=mid+1;
     62         }
     63         id1=l;
     64         l = g[i][0].first,r = g[i][0].second;
     65         while (l<=r){
     66             int mid=l+r>>1;
     67             if(cross(v[i],v[mid])<=R*2)l=mid+1;
     68             else r=mid-1;
     69         }
     70         id2=r;
     71         res+=id2-id1+1;
     72     }
     73     return res;
     74 }
     75 int main(){
     76     freopen("points.in","r",stdin);
     77     scanf("%d",&t);
     78     while (t--){
     79         scanf("%d%lld%lld",&n,&L,&R);
     80         for(int i=1;i<=n;i++){
     81             scanf("%lld%lld",&p[i].x,&p[i].y);
     82         }
     83         int ans = 0;
     84         for(int i=1;i<=n;i++){
     85             ans+=slove(i);
     86 //            printf("%d
    ",ans);
     87         }
     88         printf("%d
    ",ans);
     89     }
     90 }
     91 /**
     92 1
     93 7 7 9
     94 0 0
     95 2 0
     96 0 2
     97 10 0
     98 0 10
     99 3 3
    100 3 -3
    101 1000000000
    102 1
    103 7 5 15
    104 0 0
    105 2 0
    106 0 2
    107 10 0
    108 0 10
    109 3 3
    110 3 -3
    111 
    112 1
    113 7 1 100
    114 0 0
    115 2 0
    116 0 2
    117 10 0
    118 0 10
    119 3 3
    120 3 -3
    121  */
    122 /**
    123 1 5 1 1000000000000000000
    124 0 1000000000
    125 0 -1000000000
    126  -1000000000 0
    127  1000000000 0
    128  0 0
    129  */
    View Code
  • 相关阅读:
    Windows / Linux / MacOS 设置代理上网的方法汇总
    Centos7 配置 sendmail、postfix 端口号25、465
    CentOS 6/7 配置 sendEmail 发送邮件
    Python 发送 email 的三种方式
    Linux curl 命令模拟 POST/GET 请求
    Python + Selenium + Chrome 使用代理 auth 的用户名密码授权
    Python + Selenium + Firefox 使用代理 auth 的用户名密码授权
    Jenkins+JMeter+Ant 接口持续集成
    接口自动化、移动端、web端自动化如何做?
    pytest--命令行参数
  • 原文地址:https://www.cnblogs.com/MXang/p/10802895.html
Copyright © 2020-2023  润新知