时间: 500ms / 空间: 65536KiB / Java类名: Main

背景

小天很喜欢玩球球大作战这个游戏,大家也应该都玩过。游戏规则是:移动自己的球,移动到别人的球(一定要比自己的球小)的位置上,就可以吃掉别人的球,把别人的球的体积值加到自己的球上。还有分身、吐球等功能,但本题不考虑。

描述

作为一个OIer,小天给自己做了一个超牛的外挂:让自己的球瞬间移动到场内的任何位置!!!这意味着小天可以瞬间移动到任何一个比自己小的球上,把它吃掉。现在,小天只用外挂来瞬移,每次瞬移只能吃掉一个球。

现在房间内有n个大小不一的球,小天至少瞬移吃球多少次,才能比剩下的所有球都大呢?

样例1:

输入

3 5

10 7 4

输出

2

样例2:

输入3 5

12 2 4

输出

-1

11

输入格式

第一行两个正整数n,s,分别表示场内别人球的个数、小天的球的初始大小。

第二行n个正整数,表示这些球各自的大小。

输出格式

一行一个整数,表示变成第一至少需要吃人的次数。如果怎么也无法变成第一,则输出两行,第一行为-1,第二行为最大能达到的体积值。

备注

数据限制:

n<=30000

其他数字保证32位能存下

解法一:优先队列。10个点总用时45ms

每次把小于当前体积的数压进优先队列(大根堆),每次贪心取堆顶元素吃掉,记录何时成为最大球。

 /*by SilverN*/
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
const int mxn=;
int read(){
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 a[mxn];
int n;
priority_queue <int,vector<int>,less<int> >q;
int pos,s=;
int main(){
n=read();s=read();
int i,j;
for(i=;i<=n;i++) a[i]=read();
sort(a+,a+n+);
pos=;bool flag=;
int cnt=;
while(++cnt){
while(a[pos]<s && pos<=n){q.push(a[pos]);pos++;}
if(pos>n && !flag){
flag=;printf("%d\n",cnt-);
}
if(q.empty())break;
s+=q.top();q.pop();
}
if(!flag)printf("-1\n%d\n",s);
return ;
}

优先队列

解法二:暴力二分查找。 10个点总用时638ms

将所有数排序,每次二分查找当前能吃掉的最大球,如果这个球之前已经被吃掉了,就从此处向前暴力找第一个没被吃掉的球来吃。

 /*by SilverN*/
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
const int mxn=;
int read(){
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 a[mxn];
int smm=,mx=;
int n,s;
bool vis[mxn];
int main(){
n=read();
s=read();
int i,j;
for(i=;i<=n;i++){
a[i]=read();
smm+=a[i];
}
sort(a+,a+n+);
mx=a[n];
int cnt=;
int ans=;
bool flag=;
int pos=;
for(i=;i<=n;i++){
int l=,r=n;
int mid;
while(l<=r){
mid=(l+r)>>;
if(s<=a[mid]){
r=mid-;
}
else{
pos=mid;
l=mid+;
}
}
l=pos;
while(vis[l])l--;
s+=a[l];
cnt++;
if(l)vis[l]=;
if(s>mx && !flag){
flag=;
ans=cnt;
}
}
if(ans==)printf("-1\n%d\n",s);
else printf("%d\n",ans);
return ;
}

二分+暴力

暴力多吼呀!

最新文章

  1. nginx问题收集
  2. python Django 进阶篇
  3. 【PC端】jQuery+PHP实现浏览更多内容(jquery.more.js插件)
  4. java开发微信公众平台备忘
  5. linux ldconfig
  6. SQLServer 窗口函数
  7. devexpress datagrid 与imageEdit以及如何存图片到数据库 z
  8. Linux ---&gt; 简单socket
  9. ThinkPHP中的动态缓存(S方法)和快速缓存(F方法)(转)
  10. 由 char()函数返回的 ASCII字符集中的功能/控制字符
  11. Yii Framework2.0开发教程(4)在yii中定义全局变量
  12. AsyncTask兼容性
  13. material design 的android开源代码整理
  14. Android依赖管理与私服搭建
  15. T4 代码生成 Demo (抽奖程序)
  16. centOS7网络配置(nmcli,bonding,网络组)
  17. riot.js教程【一】简介
  18. 【BZOJ1096】【ZJOI2007】仓库建设(斜率优化,动态规划)
  19. Scrum 冲刺 第一日
  20. 拥抱开源,Office 365开发迎来新时代

热门文章

  1. python打飞机pro版
  2. 迅为4412开发板Linux设备树的镜像烧写和源码简单优化教程
  3. spark简单入门
  4. ulrlib案例-爬取百度贴吧
  5. 转 在Qt中用QAxObject来操作Excel
  6. k sum(lintcode)
  7. visual c++ build tools的安装与使用
  8. Vuex基本概念
  9. 【dp 状态压缩 单调栈】bzoj3591: 最长上升子序列
  10. redis:高可用分析