AtCoder Beginner Contest 168 F - . (Single Dot)

2 篇文章 0 订阅
1 篇文章 0 订阅

English problem plane

Time Limit: 3 sec / Memory Limit: 1024 MB

Score: 600 points

Problem

Statement There is a grass field that stretches infinitely. In this field, there is a negligibly small cow. Let (x,y) denote the point that is x cm south and y cm east of the point where the cow stands now. The cow itself is standing at (0,0).

There are also N north-south lines and M east-west lines drawn on the field. The i-th north-south line is the segment connecting the points (Ai,Ci) and (Bi,Ci), and the j-th east-west line is the segment connecting the points (Dj,Ej) and (Dj,Fj).

What is the area of the region the cow can reach when it can move around as long as it does not cross the segments (including the endpoints)? If this area is infinite, print INF instead.

Constraints

All values in input are integers between $−10^9 $and $10^9 $ (inclusive). 1≤N,M≤1000

Ai<Bi (1≤i≤N)

Ej<Fj (1≤j≤M)

The point (0,0) does not lie on any of the given segments.

Input

Input is given from Standard Input in the following format:

N 

M

A1​ B1​ C1​

:

AN​ BN​ CN​

D1​ E1​ F1​

:

DM​ EM​ FM​

Output

If the area of the region the cow can reach is infinite, print INF; otherwise, print an integer representing the area in c m 2 cm^2 cm2.

(Under the constraints, it can be proved that the area of the region is always an integer if it is not infinite.)

Sample Input 1
5 6
1 2 0
0 1 1
0 2 2
-3 4 -1
-2 6 3
1 0 1
0 1 2
2 0 2
-1 -4 5
3 -2 4
1 2 4
Sample Output 1
13

The area of the region the cow can reach is 13 c m 2 13 cm^2 13cm2.

Sample Input 2
6 1
-3 -1 -2
-3 -1 1
-2 -1 2
1 4 -2
1 4 -1
1 4 1
3 1 4
Sample Output 2
INF

中文题面

题目描述

有一片无限延伸的草地。 在这片田野里,有一头小得可以忽略不计的母牛。让(x,y)表示奶牛现在站立的位置,即以南x厘米和以东y厘米的点。牛本身站在(0,0)。
球场上还画了N条南北线和M条东西线。第i条南北线是连接点(Ai,Ci)和(Bi,Ci),而第j条东西线是连接点(Dj,Ej)和(Dj,Fj).
当牛可以四处移动时,只要它不穿过线段(包括端点),它可以到达的区域面积是多少?如果这个区域是无限的,输出INF。

输入格式

N M
A1 B1 C1
.
.
AN BN CN
D1 E1 F1
.
.
DM EM FM

输出格式

如果牛能到达的区域的面积是无限的,输出INF。否则,输出一个整数,表示是能到达的区域面积,单位是cm2 。
(在约束条件下,可以证明区域的面积如果不是无限大,则始终是整数。)

样例输入1
5 6
1 2 0
0 1 1
0 2 2
-3 4 -1
-2 6 3
1 0 1
0 1 2
2 0 2
-1 -4 5
3 -2 4
1 2 4
样例输出1
13
样例输入2
6 1
-3 -1 -2
-3 -1 1
-2 -1 2
1 4 -2
1 4 -1
1 4 1
3 1 4
样例输出2
INF
数据范围与提示
输入中的所有值都是-109−109之间的整数(含)。
1≤N,M≤1000
Ai<Bi(1≤i≤N)
Ej<Fj(1≤j≤M)
点(0,0)不在任何给定的线段上。

方法

把每一条东西线的Y坐标和南北线的X坐标记录下来并排序和去重

把草地压缩成N*M的表格

在每两个格子之间加一个格子(如果有两个格子之间边阻挡,就标记)

在边缘一圈标记掉

最后在包含坐标(0,0)的格子开始跑一遍floodfill(洪水填充法)就能Accepted

代码
#include<cstdio>
long long n,m,N,M,v,t,L=0,R=0,Z=0,X,Y,a[1005][3],b[1005][3],kx[10005],ky[1005],tx[1005],ty[1005],map[2005][2005],d[4000005][2],f[2005][2005],sum=0;
long long dx[4]={0,1,0,-1},dy[4]={1,0,-1,0};
void pxa(long long x,long long y){
    long long l=x,r=y,mid=a[(l+r)/2][0];
    while(l<=r){
        while(a[l][0]<mid)l++;
        while(a[r][0]>mid)r--;
        if(l<=r){
            v=a[l][0];a[l][0]=a[r][0];a[r][0]=v;
            v=a[l][1];a[l][1]=a[r][1];a[r][1]=v;
            v=a[l][2];a[l][2]=a[r][2];a[r][2]=v;
            l++;r--;
        }
    }
    if(x<r)pxa(x,r);
    if(l<y)pxa(l,y);
    return;
}
void pxb(long long x,long long y){
    long long l=x,r=y,mid=b[(l+r)/2][0];
    while(l<=r){
        while(b[l][0]<mid)l++;
        while(b[r][0]>mid)r--;
        if(l<=r){
            v=b[l][0];b[l][0]=b[r][0];b[r][0]=v;
            v=b[l][1];b[l][1]=b[r][1];b[r][1]=v;
            v=b[l][2];b[l][2]=b[r][2];b[r][2]=v;
            l++;r--;
        }
    }
    if(x<r)pxb(x,r);
    if(l<y)pxb(l,y);
    return;
}
int main(){
    scanf("%lld %lld",&n,&m);
    for(int i=1;i<=n;i++)scanf("%lld %lld %lld",&a[i][1],&a[i][2],&a[i][0]);
    for(int i=1;i<=m;i++)scanf("%lld %lld %lld",&b[i][0],&b[i][1],&b[i][2]);
    pxa(1,n);pxb(1,m);N=1;M=1;
    kx[1]=a[1][0];ky[1]=b[1][0];tx[1]=1;ty[1]=1;
    for(int i=2;i<=n;i++){if(a[i][0]!=a[i-1][0])kx[++N]=a[i][0];tx[i]=N;}
    for(int i=2;i<=m;i++){if(b[i][0]!=b[i-1][0])ky[++M]=b[i][0];ty[i]=M;}
    if(kx[1]>0||ky[1]>0||kx[N]<0||ky[M]<0){printf("INF");return 0;}
    for(int i=1;i<=N;i++)map[i*2-1][1]=map[i*2-1][2*M+1]=-2;
    for(int i=1;i<=M;i++)map[1][i*2-1]=map[2*N+1][i*2-1]=-2;
    map[2*N+1][2*M+1]=-2;
    for(int i=1;i<=N;i++){
        for(int j=1;j<=M;j++){
            map[i*2][j*2]=-1;
        }
    }
    for(int i=2;i<=N;i++){
        for(int j=2;j<=M;j++){
            map[i*2-1][j*2-1]=(kx[i]-kx[i-1])*(ky[j]-ky[j-1]);
            if((kx[i]>=0&&kx[i-1]<=0)&&(ky[j]>=0&&ky[j-1]<=0)){
                R++;d[R][0]=i*2-1;d[R][1]=j*2-1;f[i*2-1][j*2-1]=1;sum+=map[i*2-1][j*2-1];
            }
        }
    }
    t=1;
    for(int i=2;i<=N;i++){
        for(int j=1;j<=m;j++){
            if(b[j][1]<=kx[i-1]&&kx[i]<=b[j][2]){
                map[i*2-1][ty[j]*2]=-1;
            }
        }
    }
    t=1;
    for(int i=2;i<=M;i++){
        for(int j=1;j<=n;j++){
            if(a[j][1]<=ky[i-1]&&ky[i]<=a[j][2]){
                map[tx[j]*2][i*2-1]=-1;
            }
        }
    }
    while(L<R){
        L++;
        for(int i=0;i<4;i++){
            X=d[L][0]+dx[i];Y=d[L][1]+dy[i];
            if(X>0&&X<=2*N+1&&Y>0&&Y<=2*M+1){
                if(f[X][Y]==0&&map[X][Y]!=-1){
                    if(map[X][Y]==-2){printf("INF");return 0;}
                    else{
                        f[X][Y]=1;sum+=map[X][Y];
                        R++;d[R][0]=X;d[R][1]=Y;
                    }
                }
            }
        }
    }
    printf("%lld",sum);
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值