• Bzoj1818: [Cqoi2010]内部白点 && Tyvj P2637 内部白点 扫描线,树状数组,离散化


    1818: [Cqoi2010]内部白点

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 704  Solved: 344
    [Submit][Status][Discuss]

    Description

    无限大正方形网格里有n个黑色的顶点,所有其他顶点都是白色的(网格的顶点即坐标为整数的点,又称整点)。每秒钟,所有内部白点同时变黑,直到不存在内部白点为止。你的任务是统计最后网格中的黑点个数。 内部白点的定义:一个白色的整点P(x,y)是内部白点当且仅当P在水平线的左边和右边各至少有一个黑点(即存在x1 < x < x2使得(x1,y)和(x2,y)都是黑点),且在竖直线的上边和下边各至少有一个黑点(即存在y1 < y < y2使得(x,y1)和(x,y2)都是黑点)。

    Input

    输入第一行包含一个整数n,即初始黑点个数。以下n行每行包含两个整数(x,y),即一个黑点的坐标。没有两个黑点的坐标相同,坐标的绝对值均不超过109。

    Output

    输出仅一行,包含黑点的最终数目。如果变色过程永不终止,输出-1。

    Sample Input

    4
    0 2
    2 0
    -2 0
    0 -2

    Sample Output

    5

    数据范围
    36%的数据满足:n < = 500
    64%的数据满足:n < = 30000
    100%的数据满足:n < = 100000

    HINT

     

    题解 :

      -1的情况很好搞,在纸上画画就看出来了。(黄学长博客中有证明:http://hzwer.com/1836.html )

            之后我们发现,其实只用找有多少个白点上下左右都为黑点。

      然后我们就想到了可以用扫描线。。。

      把每个竖线和横线找到。

      从下往上扫描,

      遇到竖线的下端点就 让坐标+1。

      遇到横线就去统计 在 l~r 中的和。

      遇到竖线的上端点就 让坐标 -1。

      这个用树状数组维护一下即可。

    代码和对拍:

      丑陋的对拍:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define INF 1e9
     4 int a[2000][2000],X[10010],Y[10010];
     5 int main()
     6 {
     7     int sum,i,j,x,y,xx,yy,xx1,yy1,dx,dy,n,pd;
     8     scanf("%d",&n);
     9     xx=-INF;yy=-INF;xx1=INF;yy1=INF;
    10     for(i=1;i<=n;i++){scanf("%d %d",&X[i],&Y[i]);xx=max(xx,X[i]);yy=max(yy,Y[i]);xx1=min(xx1,X[i]);yy1=min(yy1,Y[i]);}
    11     dx=(int)fabs(xx1);dy=(int)fabs(yy1);
    12     for(i=1;i<=n;i++)
    13     {
    14         X[i]+=dx;Y[i]+=dy;
    15         a[X[i]][Y[i]]=1;
    16     }
    17     sum=n;
    18     for(i=xx1+dx;i<=xx+dx;i++)
    19     {
    20         for(j=yy1+dy;j<=yy+dy;j++)
    21         {
    22             if(a[i][j]==0)
    23             {
    24                 pd=0;
    25                 x=i;y=j;
    26                 while(x<=xx+dx){if(a[x][y]==1){pd++;break;}x++;}
    27                 x=i;y=j;
    28                 while(y<=yy+dy){if(a[x][y]==1){pd++;break;}y++;}
    29                 x=i;y=j;
    30                 while(x>=xx1+dx){if(a[x][y]==1){pd++;break;}x--;}
    31                 x=i;y=j;
    32                 while(y>=yy1+dy){if(a[x][y]==1){pd++;break;}y--;}
    33                 if(pd==4)sum++;
    34             }
    35         }
    36     }
    37     printf("%d",sum);
    38     return 0;
    39 }
    40 
    41 
    42 
    43 
    44 
    45 
    46 #include<bits/stdc++.h>
    47 using namespace std;
    48 bool vis[2010][2010];
    49 int add=1000;
    50 int main()
    51 {
    52     srand(time(0));
    53     int n,i,x,y;
    54     n=rand()%1000+1;
    55     printf("%d
    ",n);
    56     for(i=1;i<=n;i++)
    57     {
    58         while(1)
    59         {
    60             x=rand()%1000-500;y=rand()%1000-500;
    61             if(vis[x+add][y+add]==false)
    62             {
    63                 vis[x+add][y+add]=true;
    64                 break;
    65             }
    66         }
    67         printf("%d %d
    ",x,y);
    68     }
    69     return 0;
    70 }
    View Code

         AC程序

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define MAXN 100010
      4 struct node
      5 {
      6     int x,y;
      7 }p[MAXN];
      8 struct NODE
      9 {
     10     int x,y,pos;
     11 }pp[MAXN];
     12 struct Au
     13 {
     14     int l,r,t;
     15 }s[MAXN*3];//这一定要开三倍.
     16 int BIT[MAXN],n,xx[MAXN];
     17 int read()
     18 {
     19     int s=0,fh=1;char ch=getchar();
     20     while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
     21     while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
     22     return s*fh;
     23 }
     24 bool cmp1(NODE a,NODE b)
     25 {
     26     if(a.y==b.y)return a.x<b.x;
     27     return a.y<b.y;
     28 }
     29 bool cmp2(NODE a,NODE b)
     30 {
     31     if(a.x==b.x)return a.y<b.y;
     32     return a.x<b.x;
     33 }
     34 bool cmp3(Au a,Au b)
     35 {
     36     if(p[a.l].y==p[b.l].y)return p[a.l].x<p[a.l].x;
     37     return p[a.l].y<p[b.l].y;
     38 }
     39 int lowbit(int o){return o&(-o);}
     40 void Add(int k,int add)
     41 {
     42     while(k<=n)
     43     {
     44         BIT[k]+=add;
     45         k+=lowbit(k);
     46     }
     47 }
     48 int Sum(int k)
     49 {
     50     int sum=0;
     51     while(k>0)
     52     {
     53         sum+=BIT[k];
     54         k-=lowbit(k);
     55     }
     56     return sum;
     57 }
     58 int main()
     59 {
     60     int i,cnt,sum,cx,wx,wx1;
     61     n=read();
     62     for(i=1;i<=n;i++){p[i].x=read();p[i].y=read();xx[i]=p[i].x;pp[i].x=p[i].x;pp[i].y=p[i].y;pp[i].pos=i;}
     63     sort(pp+1,pp+n+1,cmp1);//按纵坐标从小到大排,纵坐标相等按横坐标从小到大排.(处理出来横线.)
     64     cnt=0;
     65     for(i=1;i<n;i++)//存储横线要存左右端点坐标.
     66     {
     67         if(pp[i].y==pp[i+1].y)
     68         {
     69             s[++cnt].l=pp[i].pos;s[cnt].r=pp[i+1].pos;s[cnt].t=0;
     70         }
     71     }
     72     sort(pp+1,pp+n+1,cmp2);
     73     for(i=1;i<n;i++)//存储竖线只用存上下端点.
     74     {
     75         if(pp[i].x==pp[i+1].x)
     76         {
     77             s[++cnt].l=pp[i].pos;s[cnt].r=pp[i].pos;s[cnt].t=1;//下端点.
     78             s[++cnt].l=pp[i+1].pos;s[cnt].r=pp[i+1].pos;s[cnt].t=-1;//上端点.
     79         }
     80     }
     81     sort(s+1,s+cnt+1,cmp3);
     82     /*for(i=n;i>1;i--)
     83       {
     84       if(p[s[i].l].y==p[s[i-1].l].y)
     85       }*/
     86     memset(BIT,0,sizeof(BIT));sum=n;
     87     sort(xx+1,xx+n+1);
     88     cx=unique(xx+1,xx+n+1)-(xx+1);
     89     //sort(yy+1,yy+n+1);
     90     //cy=unique(yy+1,yy+n+1)-(yy+1);
     91     for(i=1;i<=cnt;i++)
     92     {
     93         if(s[i].t==0)
     94         {
     95             wx=lower_bound(xx+1,xx+cx+1,p[s[i].r].x)-(xx+1);
     96             wx1=lower_bound(xx+1,xx+cx+1,p[s[i].l].x)-(xx+1);
     97             sum+=(Sum(wx)-Sum(wx1+1));
     98         }
     99         else
    100         {
    101             wx=lower_bound(xx+1,xx+cx+1,p[s[i].l].x)-(xx+1);
    102             //if(wx==0&&xx[1]==p[s[i].l].x)wx=1;
    103             Add(wx+1,s[i].t);
    104         }
    105     }
    106     printf("%d",sum);
    107     fclose(stdin);
    108     fclose(stdout);
    109     return 0;
    110 }
    View Code

      

    id

  • 相关阅读:
    股票交易接口
    股票自动买卖
    安信证券接口的demo做得不好。
    MEF bug? 无法加载外部的DLL
    如何移植行情软件的指标到千发股票自动交易软件?
    股票策略交易
    博客园自动关注病毒 只活了一小会儿。
    Float 运算的怪异性
    文件大小和占用空间为何不一样
    做最好的自己
  • 原文地址:https://www.cnblogs.com/Var123/p/5265720.html
Copyright © 2020-2023  润新知