题解 P1496 【火烧赤壁】

蒟蒻的第一篇题解,其实这道题是标准的离散化,模拟可以过,但是就没有训练效果了。我们首先先看数据,n<=20000,数据不多,但是范围大(-10^9<=Ai,Bi<=10^9),这时,就可以用离散化了,我们先定义两个数组,记录坐标,再全部赋给一个新的数组,进行排序,就可以判断是否可用*(flag判断),再通过一个find函数,找到原位置,就可以算了。但是本题卡时间,优化一下就行(快读,氧气优化之类的)

关于判断是否可用,举个栗子

有两对线段(x1,y1)(x2,y2) 如果x1>y2或x2>y1,那么(y2,x1)段或(y1,x2)段无用

#pragma GCC optimize(2)//手动o2
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
long n,m=1,ans=0;//m记录坐标数
long c[40100]={0};
//因为c要把起点与终点存下来,所以开40100
int a[20100],b[20100];//a存起点,b存终点
bool flag[40100];//判断是否有效
inline void read(long &x)//快读
{
    x=0; 
    int f=1; 
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-') 
        f=-1; 
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    x*=f;
}
inline long find(long key)//找原来位置
{
    for(int i=1;i<=m;++i)
    {
        if(c[i]==key)
        return i;
    }
}
int main()
{
    read(n);
    for(long i=1;i<=n;++i)
    {
        read(a[i]);
        read(b[i]);
        c[m]=a[i];
        m++;
        c[m]=b[i];
        m++;
    }//把a,b存入c数组里去
    sort(c+1,c+m+1);//排序坐标
    for(long i=1;i<=n;++i)
    {
        a[i]=find(a[i]);
        b[i]=find(b[i])-1;//找原位置
        for(int j=a[i];j<=b[i];++j)
        flag[j]=true;//为有效
    }
    for(long i=1;i<=m;++i)
    {
        if(flag[i])
        ans+=c[i+1]-c[i];//有效,加入ans
    }
    printf("%ld",ans);
}

蒟蒻瑟瑟发抖,%%各位大佬

猜你喜欢

转载自blog.csdn.net/qq_42701791/article/details/81840368