题解 P1496 【火烧赤壁】

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

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

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

 1 #pragma GCC optimize(2)//手动o2
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstdio>
 5 #include<cmath>
 6 #include<cstring>
 7 using namespace std;
 8 long n,m=1,ans=0;//m记录坐标数
 9 long c[40100]={0};
10 //因为c要把起点与终点存下来,所以开40100
11 int a[20100],b[20100];//a存起点,b存终点
12 bool flag[40100];//判断是否有效
13 inline void read(long &x)//快读
14 {
15     x=0; 
16     int f=1; 
17     char ch=getchar();
18     while(ch<'0'||ch>'9')
19     {
20         if(ch=='-') 
21         f=-1; 
22         ch=getchar();
23     }
24     while(ch>='0'&&ch<='9')
25     {
26         x=x*10+ch-'0';
27         ch=getchar();
28     }
29     x*=f;
30 }
31 inline long find(long key)//找原来位置
32 {
33     for(int i=1;i<=m;++i)
34     {
35         if(c[i]==key)
36         return i;
37     }
38 }
39 int main()
40 {
41     read(n);
42     for(long i=1;i<=n;++i)
43     {
44         read(a[i]);
45         read(b[i]);
46         c[m]=a[i];
47         m++;
48         c[m]=b[i];
49         m++;
50     }//把a,b存入c数组里去
51     sort(c+1,c+m+1);//排序坐标
52     for(long i=1;i<=n;++i)
53     {
54         a[i]=find(a[i]);
55         b[i]=find(b[i])-1;//找原位置
56         for(int j=a[i];j<=b[i];++j)
57         flag[j]=true;//为有效
58     }
59     for(long i=1;i<=m;++i)
60     {
61         if(flag[i])
62         ans+=c[i+1]-c[i];//有效,加入ans
63     }
64     printf("%ld",ans);
65 }

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

posted @ 2018-08-23 21:28  __mashiro  阅读(220)  评论(0编辑  收藏  举报