The 10th Shandong Provincial Collegiate Programming Contest H.Tokens on the Segments(贪心+优先级队列 or 贪心+暴力)
•题意
二维平面上有 n 条线段,每条线段坐标为 $(l_i,i),(r_i,i)$;
平面上的每个整点坐标上都可以放置一枚硬币,但是要求任意两枚硬币的横坐标不相同;
问最多有多少条线段可以放置硬币。
•题解1
考虑到当 $X=x$ 时,最多有一条线段可以放置一枚硬币;
那么,我们可以从左到右查找最多有多少条线段可以放置硬币;
定义变量 $X$ 表示 $[0,X]$ 位置已放置好硬币;
既然是按照 $x$ 来的,那么我们就需要将所有可能可以放置硬币的线段按照 $l$ 升序排列,如果 $l$ 相同,按照 $r$ 升序排列;
考虑用优先级队列,首先将所有线段放入优先级队列 $q$ 中,并定义 $X=0$;
每次选择从 $q$ 的队头取出 $l$ 小的线段,判断这条线段的 $l'$ 与 $X$ 的位置关系:
①如果 $l' \leq X$,说明当前这条线段的 $[l',X]$ 位置 不能放置硬币,只能考虑 $[X+1,r']$ 位置是否还可以放置硬币;
那么,此时,我们就将 $[X+1,r_i]$ 丢到 $q$ 中,代表可能从 $[X+1,r']$ 中选择某位置放置硬币;
②如果 $l' > X$,说明 $[X,l')$ 间无可放置硬币的线段,那么我们要选择一枚硬币放置在 $l'$ 处,即当前这条线段上,并更新 $X=l'$;
•Code
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+; int n;
struct Heap
{
int l,r;
bool operator < (const Heap &obj)const
{
if(l != obj.l)
return l > obj.l;
return r > obj.r;
}
};
priority_queue<Heap >q; int Solve()
{
int X=;
int ans=;
while(!q.empty())
{
Heap tmp=q.top();
q.pop(); /**
如果 tmp.l <= X,那么[tmp.l,X]是已求出最解的位置
但是[X+1,tmp.r] 还是没有放置硬币的
所以当前线段还是有可能在[X+1,tmp.rr]区间放置一枚硬币的
所以将其加入到q中
*/
if(tmp.l <= X && X+ <= tmp.r)
q.push({X+,tmp.r});
else if(tmp.l > X)///如果tmp.l > X,更新ans,X
{
ans++;
X=tmp.l;
}
}
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
while(!q.empty())
q.pop(); scanf("%d",&n);
for(int i=;i <= n;++i)
{
int l,r;
scanf("%d%d",&l,&r);
q.push({l,r});
}
printf("%d\n",Solve());
}
return ;
}
•题解2
贪心+暴力
贪心策略:按 $r$ 从小到大排,$r$ 相同按 $l$ 从小到大排;
从 1~n 遍历每个线段,对于第 i 条线段,暴力查找 $[l,r]$ 最左的为放置硬币的空位置;
•Code
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
const int maxn=1e5+; int n;
set<int >_set;
struct Date
{
int l,r;
int len;
bool operator < (const Date &obj) const
{
return r < obj.r;
}
}_date[maxn]; int Solve()
{
sort(_date+,_date+n+);
_set.clear(); int ans=;
for(int i=;i <= n;++i)
{
int l=_date[i].l;
int r=_date[i].r;
for(int j=l;j <= r;++j)
{
if(_set.find(j) == _set.end())///查找第i条线段可以放置硬币的最左的位置
{
_set.insert(j);
ans++;
break;
}
}
}
return ans;
}
int main()
{
int test;
scanf("%d",&test);
while(test--)
{
scanf("%d",&n);
for(int i=;i <= n;++i)
{
scanf("%d%d",&_date[i].l,&_date[i].r);
_date[i].len=_date[i].r-_date[i].l+;
}
printf("%d\n",Solve());
}
return ;
}
•题解2分析
如果输入 1e5 个线段,所有线段的左右端点全部为 [1,1e9];
那么,这个算法的时间复杂度为 O(n2logn);
这个时间复杂度在打比赛的时候是不敢想的啊;
虽然不能说是正解,但可以借鉴一下其贪心的思路(tql);
•疑惑
这道题在离散化后跑一边方法①的代码wa了???
感觉,离散化后不影响结果啊??
The 10th Shandong Provincial Collegiate Programming Contest H.Tokens on the Segments(贪心+优先级队列 or 贪心+暴力)的更多相关文章
- The 10th Shandong Provincial Collegiate Programming Contest(11/13)
$$The\ 10th\ Shandong\ Provincial\ Collegiate\ Programming\ Contest$$ \(A.Calandar\) 签到 //#pragma co ...
- The 10th Shandong Provincial Collegiate Programming Contest
目录 Contest Info Solutions A. Calandar B. Flipping Game C. Wandering Robot D. Game on a Graph E. BaoB ...
- The 10th Shandong Provincial Collegiate Programming Contest 2019山东省赛游记+解题报告
比赛结束了几天...这篇博客其实比完就想写了...但是想等补完可做题顺便po上题解... 5.10晚的动车到了济南,没带外套有点凉.酒店还不错. 5.11早上去报道,济南大学好大啊...感觉走了一个世 ...
- The 10th Zhejiang Provincial Collegiate Programming Contest
Applications http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5008 string set 专场 #include& ...
- zoj The 12th Zhejiang Provincial Collegiate Programming Contest May Day Holiday
http://acm.zju.edu.cn/onlinejudge/showContestProblem.do?problemId=5500 The 12th Zhejiang Provincial ...
- zoj The 12th Zhejiang Provincial Collegiate Programming Contest Capture the Flag
http://acm.zju.edu.cn/onlinejudge/showContestProblem.do?problemId=5503 The 12th Zhejiang Provincial ...
- zoj The 12th Zhejiang Provincial Collegiate Programming Contest Team Formation
http://acm.zju.edu.cn/onlinejudge/showContestProblem.do?problemId=5494 The 12th Zhejiang Provincial ...
- zoj The 12th Zhejiang Provincial Collegiate Programming Contest Beauty of Array
http://acm.zju.edu.cn/onlinejudge/showContestProblem.do?problemId=5496 The 12th Zhejiang Provincial ...
- zoj The 12th Zhejiang Provincial Collegiate Programming Contest Lunch Time
http://acm.zju.edu.cn/onlinejudge/showContestProblem.do?problemId=5499 The 12th Zhejiang Provincial ...
随机推荐
- Effective Modern C++:07并发API
C++11的志伟功勋之一,就是将并发融入了语言和库中,因此在C++的历史上,程序员可以首次跨越所有平台撰写具有标准行为的多线程程序. 35:优先选用基于任务而非基于线程的程序设计 如果需要以异步的方式 ...
- 深入理解 Node.js 进程与线程
原文链接: https://mp.weixin.qq.com/s?__biz=MzAxODE2MjM1MA==&mid=2651557398&idx=1&sn=1fb991da ...
- Asterisk项目概述
Asterisk是一个开源的软件包,通常运行在Linux操作系统平台上.Asterisk可以用三种协议来实现VoIP,同时可以与目前电话使用的标准硬件进行交互通信,Asterisk在实现VoIP时,不 ...
- Directx11教程(58) 鼠标控制摄像机
原文:Directx11教程(58) 鼠标控制摄像机 本篇教程我们实现鼠标旋转摄像机的操作.主要就是按下鼠标左键的时候,根据鼠标的移动对摄像机进行pitch, raw的组合旋转.具体修改 ...
- Directx11教程(46) alpha blend(3)
原文:Directx11教程(46) alpha blend(3) 现在我们尝试改变box的贴图,使用一张带alpha的dds文件wirefence.dds, 用directx textu ...
- Directx11教程38 纹理映射(8)
原文:Directx11教程38 纹理映射(8) 上篇日志中,我们用纹理和光照颜色调制的方式得到最终颜色,本章我们尝试用纹理采样的颜色,直接做为材质的漫反射系数Kd,并用它来做光照计算,最后 ...
- pl/sql基础知识—过程快速入门
n 过程 过程用于执行特定的操作,当建立过程时,既可以指定输入参数(in),也可以指定输出参数(out),通过在过程中使用输入参数,可以将数据传递到执行部分:通过使用输出参数可以将执行部分的数据传递 ...
- QT UI 线程为什么卡死?
我的工程是由三个线程处理不同任务构成的,其中UI用于显示,还有数据处理和数据接收发送线程. 在运行的过程中发现由于数据处理线程不及时,超过了设定的100ms,导致UI卡死,几个周期后又恢复,接着又卡死 ...
- 判断php的运行模式
我们一般情况下,都是在apache下面运行我们的php程序,当然也有些人是用IIS环境的 我们要是想知道我们目前运行的环境是什么的话,那我们可以用函数php_sapi_name()来测试 代码: &l ...
- 注意特殊情况!最长上升子序列!!poj2533
poj 2533 简单的动归.用O(n^2)的算法也能过.但是有个细节!刚开始ans初始化为0时是错的!!!要初始化为1.因为只有1个数的时候,下面的循环是不会执行的.....或者特判.. #incl ...