洛谷P1496 火烧赤壁 (模拟/离散化+差分)
分析可知:将起点和终点按照从小到大的顺序排序,对答案不会产生影响
所以此时我们得到一种模拟做法:
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=2e4+10; 4 int n,a[N],b[N],ans; 5 //模拟做法 6 int main(){ 7 scanf("%d",&n); 8 for(int i=1;i<=n;i++) 9 scanf("%d%d",&a[i],&b[i]); 10 sort(a+1,a+n+1);sort(b+1,b+n+1); 11 for(int i=1;i<=n;i++){ 12 ans+=b[i]-a[i]; 13 if(i!=n)//不是最后一条线段 14 if(b[i]>a[i+1]) ans-=b[i]-a[i+1];//减去重复的 15 } 16 cout<<ans; 17 }
注意可能会有重复的,要减去。
当然,我们还可以离散化(虽然说没有必要):
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=2e4+10; 4 int n,ans,temp,cnt,a[N],b[N],x[2*N]; 5 int f[2*N];//判断是否有效 6 //离散化 7 int main(){ 8 scanf("%d",&n); 9 for(int i=1;i<=n;i++){ 10 scanf("%d%d",&a[i],&b[i]); 11 x[++cnt]=a[i];x[++cnt]=b[i]; 12 } 13 sort(x+1,x+cnt+1); 14 cnt=unique(x+1,x+cnt+1)-x-1; 15 for(int i=1;i<=n;i++){ 16 a[i]=lower_bound(x+1,x+cnt+1,a[i])-x; 17 b[i]=lower_bound(x+1,x+cnt+1,b[i])-x; 18 f[a[i]]++;f[b[i]]--;//差分小优化 19 } 20 for(int i=1;i<=cnt;i++){ 21 temp+=f[i]; 22 if(temp) ans+=x[i+1]-x[i];//累加答案 23 } 24 cout<<ans; 25 }
什么是有效?比如:
有两对线段(x1,y1)(x2,y2) 如果x1>y2或x2>y1,那么(y2,x1)段或(y1,x2)段无用
因为排序后对答案没有影响,所以这种方法是正确的。
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!