cogs1682. [HAOI2014]贴海报 x
2024-10-06 21:10:45
1682. [HAOI2014]贴海报
★★☆ 输入文件:ha14d.in
输出文件:ha14d.out
简单对比
时间限制:1 s 内存限制:256 MB
【题目描述】
Bytetown城市要进行市长竞选,所有的选民可以畅所欲言地对竞选市长的候选人发表言论。为了统一管理,城市委员会为选民准备了一个张贴海报的electoral墙。
张贴规则如下:
1.electoral墙是一个长度为N个单位的长方形,每个单位记为一个格子;
2.所有张贴的海报的高度必须与electoral墙的高度一致的;
3.每张海报以“A B”表示,即从第A个格子到第B个格子张贴海报;
4.后贴的海报可以覆盖前面已贴的海报或部分海报。
现在请你判断,张贴完所有海报后,在electoral墙上还可以看见多少张海报。
【输入格式】
第一行: N M 分别表示electoral墙的长度和海报个数
接下来M行: Ai Bi 表示每张海报张贴的位置
【输出格式】
输出贴完所有海报后,在electoral墙上还可以看见的海报数。
【样例输入】
100 5
1 4
2 6
8 10
3 4
7 10
【样例输出】
4
【提示】
【约束条件】
1 0<= N <= 10000000 1<=M<=1000 1<= Ai <= Bi <=10000000
所有的数据都是整数。数据之间有一个空格
思路:
1)首先这道题暴力可以拿80分!(在luogu上可以AC!!!!)
2)然后考场上作死写了个并查集。。。61分
3)正解:
①线段树(然而我没写~)
②浮水法
坑点:
因为给出的是所位于的块,不是左右端点,所以在处理浮水法的时候记得要右端点+1,或者左端点-1
上代码:
1)暴力
#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
using namespace std; const int M = 1e7 + ;
int n,m,l,r,ans;
int a[M],v[M]; inline int reads()
{
int x=,f=;char ch=getchar();
while(ch<'' || ch>'')
{if(ch=='-') f=-;ch=getchar();}
while(ch>='' && ch<='')
{x=*x+ch-'';ch=getchar();}
return x*f;
} int main()
{
freopen("ha14d.in","r",stdin);
freopen("ha14d.out","w",stdout);
n=reads(),m=reads();
for(int i=;i<=m;i++)
{
l=reads(),r=reads();
if(r<l) swap(l,r);
for(int j=l;j<=r;j++)
a[j]=i;
}
for(int i=;i<=n;i++)
{
if(!v[a[i]] && a[i])
{
ans++;
v[a[i]]=;
}
}
printf("%d",ans);
return ;
}
2)作死并查集
#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio> using namespace std; inline int reads()
{
int x=,f=;char ch=getchar();
while(ch<'' || ch>'')
{if(ch=='-') f=-;ch=getchar();}
while(ch>='' && ch<='')
{x=*x+ch-'';ch=getchar();}
return x*f;
} const int M = 1e7 + ; ///多开几个
const int N = ;
int n,m;
int f[M];
int ans[M],anse;
int Ls[N],Rs[N]; int getf(int x)
{return f[x] == x ? x : f[x] = getf(f[x]);} int main()
{
freopen("ha14d.in","r",stdin);
freopen("ha14d.out","w",stdout);
n=reads();m=reads(); ///n是n块,不是左右端点!!!
for(int i=;i<=n+;i++)
f[i]=i;
for(int i=;i<=m;i++) ///m组数据
{ ///手动从1开始,从0不会...
Ls[i]=reads();
Rs[i]=reads()+; ///因为给出不是点的坐标,是块的坐标
}
int l,r;
for(int i=m;i>=;i--) ///逆序张贴,因为只需要的是最后的能看到的海报
{
l=Ls[i],r=Rs[i]; ///左右端点
if(l>r) swap(l,r); ///maybe?会出现"left">"right"的情况(考虑最坏情况,以防万一,以前做过一个题就是恶心的数据!)
for(int j=getf(l);j<=r;j=getf(j+))
{
f[getf(j)]=getf(j+); ///将当前被张贴报纸的父结点手动设置到最后一个的父结点
/// ans[j]=i;
ans[i]++;
if(getf()==n+) break; ///表示已经贴完
}
} for(int i=;i<=n+;i++)
{
/// printf("%d=%d\n",i,ans[i]); ///输出调试???
if(ans[i]) anse++;
}
printf("%d\n",anse); return ;
}
3)正解(浮水法)
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std; const int M = ;
int n,m,ans=;
bool v[M]; struct U {
int l,r,id;
//id 为第几张海报
}t[M]; inline int reads()
{
int x=,f=;char ch=getchar();
while(ch<'' || ch>'')
{if(ch=='-') f=-;ch=getchar();}
while(ch>='' && ch<='')
{x=*x+ch-'';ch=getchar();}
return x*f;
} void swim(int ql,int qr,int nowid,int preid)
{
if(v[preid])
return;
while(nowid<=m && (qr<=t[nowid].l || ql>=t[nowid].r))
nowid++;
if(nowid>m)
{
v[preid]=true;
ans++;
return;
}
if(ql<t[nowid].l && qr>t[nowid].l)
swim(ql,t[nowid].l,nowid+,preid);
if(ql<t[nowid].r && qr>t[nowid].r)
swim(t[nowid].r,qr,nowid+,preid);
} int main()
{
freopen("ha14d.in","r",stdin);
freopen("ha14d.out","w",stdout);
n=reads();m=reads();
for(int i=;i<=m;i++)
{
t[i].l=reads(),t[i].r=reads()+;
t[i].id=i;
}
for(int i=m-;i>=;i--)
swim(t[i].l,t[i].r,i+,i);
printf("%d",ans);
return ;
}
最新文章
- mysql 2003 10038 连接不上的解决
- iOS开发--appstore应用上架
- Spark Streaming揭秘 Day14 State状态管理
- C#如何在派生类中不显示父类的一些属性以及TypeDescriptor使用
- bzoj1458
- 深入浅出scanf、getcha、gets、cin函数
- mac os x在PC上安装
- MySQL索引(1)
- 业余草双因素认证(2FA)教程
- 自定义view 波浪效果
- ECMA Script 6_数值的扩展
- mui之上拉刷新和mui-content结合解决ios上拉不回弹的bug
- php curl POST multipart/form-data与application/x-www-form-urlencode的区别
- Windows: 打开关闭网络连接的方法
- (原)docker的一个“Driver aufs failed to remove...”问题的解决
- 用纯css实现下拉菜单的几种方式
- FLV封装格式分析
- 结合cocos2d-x开发配置sublime text
- TWebBrowser静音
- 一些通过SAP ABAP代码审查得出的ABAP编程最佳实践