• XJOI网上同步训练DAY1 T2


    思路:似曾相识?...见http://www.cnblogs.com/qzqzgfy/p/5266874.html

    一看时限还是4s!,于是就开开心心地打了70%的分,就是用容斥原理,就可以n^3解决问题了。

    实际情况:10分,wtf

    我的程序:

      1 #include<algorithm>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<cstring>
      5 #include<iostream>
      6 const double eps=1e-6;
      7 int tot[505][505],n,m,K;
      8 const double Pi=acos(-1);
      9 struct Point{
     10     double x,y,ang;
     11     int id,bel;
     12     Point(){}
     13     Point(double x0,double y0):x(x0),y(y0){}
     14 }d[200005],f[200005],t[200005],p[200005];
     15 struct Line{
     16     Point s,e;
     17     Line(){}
     18     Line(Point s0,Point e0):s(s0),e(e0){}
     19 };
     20 int sgn(double x){
     21     if (x<-eps)  return -1;
     22     if (x>eps) return 1;
     23     return 0;
     24 }
     25 bool cmp(Point p1,Point p2){
     26     return p1.ang<p2.ang;
     27 }
     28 double operator *(Point p1,Point p2){
     29     return p1.x*p2.y-p1.y*p2.x;
     30 }
     31 Point operator -(Point p1,Point p2){
     32     return Point(p1.x-p2.x,p1.y-p2.y);
     33 }
     34 int read(){
     35     char ch=getchar();int t=0,f=1;
     36     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
     37     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
     38     return t*f;
     39 }
     40 bool inter(Line p1,Line p2){
     41     if (std::min(p1.s.x,p1.e.x)>std::max(p2.s.x,p2.e.x)||
     42         std::min(p1.s.y,p1.e.y)>std::max(p2.s.y,p2.e.y)||
     43         std::min(p2.s.x,p2.e.x)>std::max(p1.s.x,p1.e.x)||
     44         std::min(p2.s.y,p2.e.y)>std::max(p1.s.y,p1.e.y))
     45     return 0;
     46     double a,b,c,d;
     47     a=(p1.e-p1.s)*(p2.e-p1.s);
     48     b=(p1.e-p1.s)*(p2.s-p1.s);
     49     c=(p2.e-p2.s)*(p1.e-p2.s);
     50     d=(p2.e-p2.s)*(p1.s-p2.s);
     51     return (a*b<=eps)&&(c*d<=eps);
     52 }
     53 void sbpianfen1(){
     54     int ans=0;
     55     for (int i=1;i<=n;i++)
     56      for (int j=1;j<=m;j++)
     57       for (int k=1;k<=K;k++)
     58        for (int l=k+1;l<=K;l++)
     59         if (inter(Line(d[i],f[j]),Line(t[k],t[l]))) ans++;
     60     printf("%d
    ",ans);    
     61 }
     62 void updata(Point p1,Point p2,int v){
     63     if (p1.bel+p2.bel!=3) return;
     64     if (p1.bel>p2.bel) std::swap(p1,p2);
     65     tot[p1.id][p2.id]+=v;
     66 }
     67 void sbpianfen2(){
     68     for (int i=1;i<=K;i++){
     69         int cnt=0;
     70         for (int j=1;j<=n;j++){
     71             p[++cnt]=d[j];p[cnt].bel=1;
     72             p[cnt].ang=atan2(d[j].y-t[i].y,d[j].x-t[i].x);
     73         }
     74         for (int j=1;j<=m;j++){
     75             p[++cnt]=f[j];p[cnt].bel=2;
     76             p[cnt].ang=atan2(f[j].y-t[i].y,f[j].x-t[i].x);
     77         }
     78         for (int j=1;j<=K;j++){
     79             if (j==i) continue;
     80             p[++cnt]=t[j];p[cnt].bel=3;
     81             p[cnt].ang=atan2(t[j].y-t[i].y,t[j].x-t[i].x);
     82         }
     83         std::sort(p+1,p+1+cnt,cmp);
     84         for (int j=1;j<=cnt;j++){
     85             p[cnt+cnt+j]=p[cnt+j]=p[j];
     86             p[cnt+j].ang=p[j].ang+2*Pi;
     87             p[cnt+cnt+j].ang=p[cnt+j].ang+2*Pi;
     88         }
     89         int l=1;int numl=(p[1].bel==3);
     90         int numj=0,numr=0,numk=0;
     91         for (int j=1;j<=cnt;j++){
     92             if (p[j].bel==3) numj++;
     93             int r=j+1;numr=numj+(p[j+1].bel==3);
     94             while (sgn(p[l].ang-p[j].ang-Pi)<0) l++,numl+=(p[l].bel==3);
     95             for (int k=j+1,numk=numj+(p[j+1].bel==3);sgn(p[k].ang-p[j].ang-Pi)<=0;k++,numk+=(p[k].bel==3)){
     96                 while (sgn(p[r+1].ang-p[k].ang-Pi)<=0) r++,numr+=(p[r].bel==3);
     97                 updata(p[k],p[j],numk-numj-(numr-numl+(p[l].bel==3)));
     98             }
     99         }
    100     }
    101     int ans=0;
    102     for (int i=1;i<=n;i++)
    103      for (int j=1;j<=m;j++)
    104       ans+=tot[i][j];
    105     printf("%d
    ",ans/2);  
    106 }
    107 int main(){
    108     n=read();
    109     for (int i=1;i<=n;i++)
    110      d[i].x=read(),d[i].y=read(),d[i].id=i;
    111     m=read();
    112     for (int i=1;i<=m;i++)
    113      f[i].x=read(),f[i].y=read(),f[i].id=i;
    114     K=read();
    115     for (int i=1;i<=K;i++)
    116      t[i].x=read(),t[i].y=read(),t[i].id=i;  
    117     if (n<=100&&m<=100&&K<=100) {sbpianfen1();return 0;} 
    118     if (n<=500&&m<=500&&K<=500) {sbpianfen2();return 0;}
    119 }

    明明应该很科学啊。。

    正解:n^2做法,枚举导弹发射井,然后极角排序,统计即可。

    具体做法:枚举发射井作为原点,然后将其他类型的点排序,然后一边for走过去,ans就加等于在半平面内的基地数乘以导弹防御塔数,再减去在每个基地后边的导弹防御塔数之和,注意删掉相同极角的部分,这样就是答案了,果然我数学太差了,毛都不会。。。

     1 #include<algorithm>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<iostream>
     6 #define ll long long
     7 const double Pi=acos(-1);
     8 ll ans=0;
     9 int d[500005][2],n,K,m;
    10 struct Point{
    11     int x,y;
    12     Point(){}
    13     Point(int x0,int y0):x(x0),y(y0){}
    14 }S[200005],T[200005],E[200005];
    15 struct node{
    16     long double w;
    17     Point p;
    18     int bz;
    19 }Q[500005];
    20 int read(){
    21     char ch=getchar();int t=0,f=1;
    22     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    23     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
    24     return t*f;
    25 }
    26 ll operator *(Point p1,Point p2){
    27     return (ll)p1.x*p2.y-(ll)p1.y*p2.x;
    28 }
    29 Point operator -(Point a,Point b){
    30     return Point(a.x-b.x,a.y-b.y);
    31 }
    32 bool cmp(const node a,const node b){
    33     return a.w<b.w||(!(a.p*b.p)&&a.bz<b.bz);
    34 }
    35 long double get(Point a){
    36     long double w=atan2(a.y,a.x);
    37     if (w<0) w=w+Pi+Pi;
    38     return w;
    39 }
    40 void calc(Point S){
    41     for (int i=1;i<=n;i++) Q[i].w=get(Q[i].p=E[i]-S),Q[i].bz=0;
    42     for (int i=1;i<=K;i++) Q[i+n].w=get(Q[i+n].p=T[i]-S),Q[i+n].bz=1;
    43     for (int i=1;i<=n+K;i++){
    44         Q[i+n+K]=Q[i];Q[i+n+K].w=Q[i].w+2*Pi;
    45         if (Q[i].bz) Q[i+n+K].bz=2;
    46     }
    47     std::sort(Q+1,Q+1+n+K+n+K,cmp);
    48     int sum=0,l=1,r=0,same=0;
    49     ll all=0,ans1=ans;
    50     for (int i=1;i<=n+K+n+K;i++){
    51         while (l<=r&&Q[d[l][0]].w+Pi<Q[i].w) all-=d[l++][1];
    52         if (Q[i].bz){
    53             if (i!=1&&Q[i].p*Q[i-1].p) same=0;
    54             ans+=(ll)(r-l+1)*sum-all;
    55             if (Q[i].bz==1) all+=sum-same,d[++r][0]=i,d[r][1]=sum-same; 
    56         }else{
    57             sum++;
    58             if (i!=1&&!(Q[i].p*Q[i-1].p)) same++;
    59             else same=1;
    60         }
    61     }
    62 }
    63 int main(){
    64     n=read();
    65     for (int i=1;i<=n;i++) E[i].x=read(),E[i].y=read();
    66     m=read();
    67     for (int i=1;i<=m;i++) S[i].x=read(),S[i].y=read();
    68     K=read();
    69     for (int i=1;i<=K;i++) T[i].x=read(),T[i].y=read();
    70     for (int i=1;i<=m;i++)
    71      calc(S[i]);
    72     printf("%lld
    ",ans); 
    73 }
  • 相关阅读:
    Android Things专题 1.前世今生
    用Power BI解读幸福星球指数
    [leetcode]Simplify Path
    字段的划分完整的问题
    k-means算法MATLAB和opencv代码
    【Oracle】RAC下的一些经常使用命令(一)
    Java中经常使用缓存Cache机制的实现
    jenkins环境自动部署
    jenkins环境搭建
    springboot单元测试@test的使用
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5614422.html
Copyright © 2020-2023  润新知