欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

2018ICPC徐州赛区网络预赛G:Trace

程序员文章站 2022-03-13 16:59:48
...

题目来源
ACM-ICPC 2018 徐州赛区网络预赛G题(计蒜客)
There’s a beach in the first quadrant. And from time to time, there are sea waves. A wave (x,y) means the wave is a rectangle whose vertexes are (0,0),(x,0), (0,y),(x,y). Every time the wave will wash out the trace of former wave in its range and remain its own trace of (x,0)>(x,y) and (0,y)>(x,y). Now the toad on the coast wants to know the total length of trace on the coast after n waves. It’s guaranteed that a wave will not cover the other completely.

Input
The first line is the number of waves n(n50000).

The next n lines,each contains two numbers x y ,(0<x,y10000000),the i-th line means the i-th second there comes a wave of (x,y), it’s guaranteed that when 1i,jnxixj and yiyj don’t set up at the same time.

Output
An Integer stands for the answer.

Hint:
As for the sample input, the answer is 3+3+1+1+1+1=10.
2018ICPC徐州赛区网络预赛G:Trace

样例输入

3
1 4
4 1
3 3

样例输出

10

题意:

海浪不断冲刷海滩,在海滩上留下矩形冲刷痕迹,并且后面的痕迹会覆盖住前面的痕迹,求最后留下的痕迹的边线总长度

解题思路:

开了两个数组,一个mapa保存输入的y的值,并从小到大排序,另一个mapb则保存当前y点到达的最大的x值,也就相当于被从y=0到对应mapa中的值的长度上已经被覆盖的x的长度,由题意得出,越靠近海的最远边线越长,即越靠近海,x或者y越大,又因为后面的痕迹一定不会被前面的痕迹所覆盖,所以从后往前计算痕迹,并不断更新mapb的值。

#include<iostream>
#include<cstdio>
#include<cstring> 
#include<algorithm>
#include<cmath>
#include<vector>
#include<deque>
#include<queue>
#include<ctime>
#define INF 0x3f3f3f3f
#define maxn  1005
using namespace std;
typedef long long LL;

int mapa[50005];
int mapb[50005];

typedef struct part{
    int x,y;
}part;

part m[50005];

int research(int left,int right,int element)//用二分法找到对应y值在mapa中的位置
{
    while(left<=right)
    {   
        int mid = (left+right)/2;
        if(mapa[mid]>element)
        {
            right = mid - 1;
        }
        else if(mapa[mid]<element)
        {
            left = mid + 1;
        }
        else 
        {
            return mid;
        }
    }
    return -1;
}


int main(){
    int n;
    memset(mapb, 0, sizeof(mapb));
    scanf("%d",&n);
    LL sum = 0;
    for(int i=0; i<n; i++){
        scanf("%d%d",&m[i].x,&m[i].y);
        mapa[i] = m[i].y;
    }
    sort(mapa,mapa+n); 
    for(int i=n-1; i>=0; i--){
        int k = research(0,n-1,m[i].y);
        int dis = m[i].x-mapb[k], p, j;
        if(dis>0) sum+=dis;//求出未被覆盖的x海岸的边线长度
        for(j=k; j>=0&&m[i].x>mapb[j]; j--){//找到最靠近海并且未被覆盖到的点
            mapb[j] = m[i].x;//更新被覆盖住的x的长度
        }
        if(j == -1) sum += m[i].y;//当此y边边线大于靠海所有的边线长度的时候,即形成一个新的覆盖面积(平行于y轴并且到0的边线)
        else sum += (m[i].y-mapa[j]);//从i点到j点形成的新的边线(平行于y轴)
    }
    printf("%lld\n", sum);
}
相关标签: 图论