UVALive 6911---Double Swords(贪心+树状数组(或集合))
题目链接
problem description
Last night, Kingdom of Light was attacked by Kingdom of Dark! The queen of Kingdom of Light, Queen Ar, was captured and locked inside a dark and creepy castle. The king of Kingdom of Light, King Ash, wants to save the queen. The castle is guarded by N dragons, conveniently numbered from 1 to N. To save Queen Ar, King Ash must kill all the dragons. The kingdom’s oracle said that in order to kill the i-th dragon, King Ash has to slay it with exactly two swords, one in each hand: one sword of length Ai units, and another sword of length between Bi and Ci , inclusive. King Ash can carry unlimited number of swords, and each sword can be used multiple times. The number of blacksmiths in the kingdom is limited, so it is important to make as few swords as possible. Besides, making swords is expensive and takes much time. Determine the minimum number of swords the kingdom has to make so that King Ash can save Queen Ar!
Input
The first line of input contains an integer T (T ≤ 20) denoting the number of cases. Each case begins with an integer N (1 ≤ N ≤ 100, 000) denoting the number of dragons which have to be killed. The next N lines each contains three integers: Ai , Bi , and Ci (1 ≤ Ai ≤ 1, 000, 000; 1 ≤ Bi ≤ Ci ≤ 1, 000, 000) denoting the swords’ length needed to kill the i-th dragon as described in the above problem statement.
Output
For each case, output ‘Case #X: Y ’, where X is the case number starts from 1 and Y is the minimum number of swords the kingdom has to make and carry in order to defeat all the dragons and save Queen Ar.
Explanation for 1st sample case: The kingdom has to make two swords in order to defeat one dragon.
Explanation for 2nd sample case: All the dragons can be defeated by three swords, for example, with lengths of: 3, 6, and 15.
• The fist dragon can be defeated by swords of length 3 and 6.
• The second dragon can be defeated by swords of length 6 and 15.
• The third dragon can be defeated by swords of length 3 and 15.
There also exists other combination of three swords.
Sample Input
4
1
7 6 8
3
3 5 10
6 11 15
3 13 15
4
1 10 20
3 50 60
2 30 40
4 70 80
2
5 100 200
150 1000 2000
Sample Output
Case #1: 2
Case #2: 3
Case #3: 8
Case #4: 3
题意:有n条恶龙,需要人同时持两把剑杀死,一把剑要求长为A,另一把剑长度在B~C之间,输入n条龙的A B C数据要求,求最少需要携带多少把剑?
思路:对于n组恶龙的数据,按照C的大小从左到右排序。先考虑数据A,即先把长度固定的剑需要的数量确定,有些A相同只计算一次,sum=0,sum+=unique(Ai)。然后考虑长度为区间(B~C)的剑,对于排好序的数据,循环处理,对于区间Bi~Ci 如果区间里没有剑或者有一把剑且长度和Ai相等,则添加一把剑长为Ci,sum++,这样可能在后面的区间中出现,使得剑的数量最少,否则不处理,表明这个区间中有剑,不需要加入剑。注意:在判断区间中剑的数量时,用树状数组很方便查询;
代码如下:
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <cstring>
#include <cmath>
#include <queue>
#include <set>
#include <bitset>
using namespace std;
const int maxn=1e6+;
int c[maxn];
bool vis[maxn];
struct Node
{
int x,y;
int z;
}node[*];
bool cmp(const Node s1,const Node s2)
{
if(s1.y==s2.y) return s1.x<s2.x;
return s1.y<s2.y;
}
int Lowbit(int t)
{
return t&(t^(t-));
}
void add(int x)
{
while(x<maxn){
c[x]++;
x+=Lowbit(x);
}
}
int sum(int x)
{
int sum=;
while(x){
sum+=c[x];
x-=Lowbit(x);
}
return sum;
}
int main()
{
int T,Case=;
cin>>T;
while(T--)
{
memset(vis,,sizeof(vis));
memset(c,,sizeof(c));
int N;
scanf("%d",&N);
for(int i=;i<N;i++)
{
scanf("%d",&node[i].z);
if(!vis[node[i].z]){
add(node[i].z);
vis[node[i].z]=true;
}
scanf("%d%d",&node[i].x,&node[i].y);
}
sort(node,node+N,cmp);
for(int i=;i<N;i++)
{
int t=sum(node[i].y)-sum(node[i].x-);
if(t==&&node[i].z>=node[i].x&&node[i].z<=node[i].y)
add(node[i].y);
else if(!t) add(node[i].y);
}
printf("Case #%d: %d\n",Case++,sum(maxn-));
}
return ;
}
这题也可以用集合,其实和上面思路差不多,用集合判断区间中是否有剑;
在网上看到有人用set写,代码如下:
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <cstring>
#include <cmath>
#include <queue>
#include <set>
#include <bitset>
using namespace std;
struct Node
{
int x,y;
int z;
}node[];
bool cmp(const Node s1,const Node s2)
{
if(s1.y==s2.y) return s1.x<s2.x;
return s1.y<s2.y;
}
set<int>s;
set<int>::iterator it; int main()
{
int T,Case=;
cin>>T;
while(T--)
{
s.clear();
int N;
scanf("%d",&N);
for(int i=;i<N;i++)
{
scanf("%d",&node[i].z);
s.insert(node[i].z);
scanf("%d%d",&node[i].x,&node[i].y);
}
sort(node,node+N,cmp);
int sum=;
for(int i=;i<N;i++)
{
it=s.lower_bound(node[i].x);
if(it!=s.end()&&*it==node[i].z) it++;
if(it==s.end()||*it>node[i].y){
if(node[i].z==node[i].y)
s.insert(-node[i].y);
//sum++;///set有去重功能;
else s.insert(node[i].y);
}
}
printf("Case #%d: %d\n",Case++,s.size()+sum);
}
return ;
}
这样写确实AC了,但我感觉有BUG 我认真看了程序,想了一个数据:
1
2
4 2 4
4 4 6
正确答案是2
运行这个程序结果是3
但是用多重集合是可以避免这个BUG的
代码如下:
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <cstring>
#include <cmath>
#include <queue>
#include <set>
#include <bitset>
using namespace std;
const int maxn=1e6+;
bool vis[maxn];
struct Node
{
int x,y;
int z;
}node[];
bool cmp(const Node s1,const Node s2)
{
if(s1.y==s2.y) return s1.x<s2.x;
return s1.y<s2.y;
}
multiset<int>s;
multiset<int>::iterator it; int main()
{
int T,Case=;
cin>>T;
while(T--)
{
memset(vis,,sizeof(vis));
s.clear();
int N;
scanf("%d",&N);
for(int i=;i<N;i++)
{
scanf("%d",&node[i].z);
if(!vis[node[i].z]){
s.insert(node[i].z);
vis[node[i].z]=true;
}
scanf("%d%d",&node[i].x,&node[i].y);
}
sort(node,node+N,cmp);
for(int i=;i<N;i++)
{
it=s.lower_bound(node[i].x);
if(it!=s.end()&&*it==node[i].z) it++;
if(it==s.end()||*it>node[i].y){
s.insert(node[i].y);
}
}
printf("Case #%d: %d\n",Case++,s.size());
}
return ;
}
/*
345
2
4 2 4
4 4 6
2
4 2 4
4 3 4
*/
UVALive 6911---Double Swords(贪心+树状数组(或集合))的更多相关文章
- 【bzoj4240】有趣的家庭菜园 贪心+树状数组
题目描述 对家庭菜园有兴趣的JOI君每年在自家的田地中种植一种叫做IOI草的植物.JOI君的田地沿东西方向被划分为N个区域,由西到东标号为1~N.IOI草一共有N株,每个区域种植着一株.在第i个区域种 ...
- UVALive 6911 Double Swords 树状数组
Double Swords 题目连接: https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8 ...
- 贪心+树状数组维护一下 Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) D
http://codeforces.com/contest/724/problem/D 题目大意:给你一个串,从串中挑选字符,挑选是有条件的,按照这个条件所挑选出来的字符集合sort一定是最后选择当中 ...
- D 洛谷 P3602 Koishi Loves Segments [贪心 树状数组+堆]
题目描述 Koishi喜欢线段. 她的条线段都能表示成数轴上的某个闭区间.Koishi喜欢在把所有线段都放在数轴上,然后数出某些点被多少线段覆盖了. Flandre看她和线段玩得很起开心,就抛给她一个 ...
- [BZOJ4240]有趣的家庭菜园(贪心+树状数组)
最后数列一定是单峰的,问题就是最小化最后的位置序列的逆序对数. 从大到小加数,每次贪心看放左边和右边哪个产生的逆序对数更少,树状数组即可. 由于大数放哪对小数不产生影响,所以正确性显然. 注意相同数之 ...
- [P4064][JXOI2017]加法(贪心+树状数组+堆)
题目描述 可怜有一个长度为 n 的正整数序列 A,但是她觉得 A 中的数字太小了,这让她很不开心. 于是她选择了 m 个区间 [li, ri] 和两个正整数 a, k.她打算从这 m 个区间里选出恰好 ...
- [luoguP2672] 推销员(贪心 + 树状数组 + 优先队列)
传送门 贪心...蒟蒻证明不会... 每一次找最大的即可,找出一次最大的,数列会分为左右两边,左边用stl优先队列维护,右边用树状数组维护.. (线段树超时了....) 代码 #include < ...
- codeforces 1249 D2 Too Many Segments (hard version) 贪心+树状数组
题意 给定n个线段,线段可以相交,第\(i\)个线段覆盖的区间为\([l_i,r_i]\),问最少删除多少个线段让覆盖每个点的线段数量小于等于k. 分析 从左往右扫每个点\(x\),若覆盖点\(x\) ...
- [JZO6401]:Time(贪心+树状数组)
题目描述 小$A$现在有一个长度为$n$的序列$\{x_i\}$,但是小$A$认为这个序列不够优美. 小$A$认为一个序列是优美的,当且仅当存在$k\in [1,n]$,满足:$$x_1\leqsla ...
随机推荐
- jdbc在mysql下一次执行多条sql脚本
默认连接mysql的时候一次只能执行一条sql.要批量执行sql需要在jdbcUrl中增加“allowMultiQueries=true”参数,完整jdbcUrl如下: jdbc:mysql://l ...
- JS实战 · 级联菜单选择省份和城市(两种)
DOM编程步骤.思路 1.定义界面: 通过html标签将数据进行封装: 2.定义一些静态样式: 利用css: 3.需要动态地完成的和用户的交互: a:明确事件源: ...
- struts1四:常用标签
struts1支持的5种标签: HTML 标签: 用来创建能够和Struts 框架和其他相应的HTML 标签交互的HTML 输入表单 Bean 标签: 在访问JavaBeans 及其属性,以及定义一个 ...
- 2013 duilib入门简明教程 -- XML基础类(7)
现在大家应该对XML描述界面不那么陌生了,那么我们做进一步介绍. 前面的教程我们写了很多代码,为的是让大家了解下基本流程,其实duilib已经对常用的操作做了很好的包装,正式使用时无需像前面的教程那样 ...
- 导入一些常用命令比如(rz),关闭防火墙外面可以访问
yum -y install lrzsz-----------导入常用命令 我在虚拟机上面启动了一个项目 这个原因是防火墙造成的,关闭防火墙 iptables -L 查看下 service ipt ...
- weblogic配置数据源
启动weblogic 管理服务器,使用管理用户登录weblogic管理控制台 打开管理控制台后,在左侧的树形域结构中,选择服务->数据源. 在右侧的窗口中,选择 新建->一般数据源 ...
- Python 日志模块 logging通过配置文件方式使用
vim logger_config.ini[loggers]keys=root,infoLogger,errorlogger [logger_root]level=DEBUGhandlers=info ...
- Owin的URL编码怎么搞?以前都是HttpUtility.UrlEncode之类的,现在连system.web都没了,肿么办?
Owin的URL编码怎么搞?以前都是HttpUtility.UrlEncode之类的,现在连system.web都没了,肿么办? 编码: Uri.EscapeDataString(name) 解码: ...
- 【原创】开源Math.NET基础数学类库使用(07)常用的数学物理常数
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 开源Math.NET基础数学类库使用总目录:[目录]开源Math.NET基础数学类库使用总目录 1.前 ...
- 瀑布流StaggeredGridView 下拉刷新
1.项目中用到了瀑布流,之前用的是PinterestLikeAdapterView这个控件 然后上拉加载更多跟下拉刷新用的是XListView ,但是加载更多或者下拉刷新的时候闪屏,对用户体验很不好 ...