zoukankan      html  css  js  c++  java
  • TYVJ4623 球球大作战·生存

    时间: 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

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

     1 /*by SilverN*/
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 #include<queue>
     8 using namespace std;
     9 const int mxn=30010;
    10 int read(){
    11     int x=0,f=1;char ch=getchar();
    12     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    13     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    14     return x*f;
    15 }
    16 int a[mxn];
    17 int n;
    18 priority_queue <int,vector<int>,less<int> >q;
    19 int pos,s=0;
    20 int main(){
    21     n=read();s=read();
    22     int i,j;
    23     for(i=1;i<=n;i++) a[i]=read();
    24     sort(a+1,a+n+1);
    25     pos=1;bool flag=0;
    26     int cnt=0;
    27     while(++cnt){
    28         while(a[pos]<s && pos<=n){q.push(a[pos]);pos++;}
    29         if(pos>n && !flag){
    30             flag=1;printf("%d
    ",cnt-1);
    31         }
    32         if(q.empty())break;
    33         s+=q.top();q.pop();
    34     }
    35     if(!flag)printf("-1
    %d
    ",s);
    36     return 0;
    37 }
    优先队列

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

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

     1 /*by SilverN*/
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 using namespace std;
     8 const int mxn=30010;
     9 int read(){
    10     int x=0,f=1;char ch=getchar();
    11     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    12     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    13     return x*f;
    14 }
    15 int a[mxn];
    16 int smm=0,mx=0;
    17 int n,s;
    18 bool vis[mxn];
    19 int main(){
    20     n=read();
    21     s=read();
    22     int i,j;
    23     for(i=1;i<=n;i++){
    24         a[i]=read();
    25         smm+=a[i];
    26     }
    27     sort(a+1,a+n+1);
    28     mx=a[n];
    29     int cnt=0;
    30     int ans=0;
    31     bool flag=0;
    32     int pos=0;
    33     for(i=1;i<=n;i++){
    34         int l=1,r=n;
    35         int mid;
    36         while(l<=r){
    37             mid=(l+r)>>1;
    38             if(s<=a[mid]){
    39                 r=mid-1;
    40             }
    41             else{
    42                 pos=mid;
    43                 l=mid+1;
    44             }
    45         }
    46         l=pos;
    47         while(vis[l])l--;
    48         s+=a[l];
    49         cnt++;
    50         if(l)vis[l]=1;
    51         if(s>mx && !flag){
    52             flag=1;
    53             ans=cnt;
    54         }
    55     }
    56     if(ans==0)printf("-1
    %d
    ",s);
    57     else printf("%d
    ",ans);
    58     return 0;
    59 }
    二分+暴力

    暴力多吼呀!

  • 相关阅读:
    WordCount
    vs2013安装及测试
    阅读程序,回答问题
    补作业:随机生成二元四则运算
    第一次合作
    漫漫“码农”路
    我的进度条
    Believe
    软件工程个人总结
    结队作业——电梯调度程序
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/5909199.html
Copyright © 2011-2022 走看看