bzoj 1816 //1816: [Cqoi2010]扑克牌

bzoj 1816 //1816: [Cqoi2010]扑克牌   //在线测评地址https://www.lydsy.com/JudgeOnline/problem.php?id=1816

更多题解,详见https://blog.csdn.net/mrcrack/article/details/90228694BZOJ刷题记录

//1816: [Cqoi2010]扑克牌
//在线测评地址https://www.lydsy.com/JudgeOnline/problem.php?id=1816
//题意叙述不清,好在样例有解释,题意也算弄明白了
//ci < = 500,000,000常规算法显然无能为力
//如n=5,套牌是指{1,2,3,4,5},这一点,题意不是很明确.
//大致的思路有了,就是难以形成有效算法
//https://blog.csdn.net/qq_36038511/article/details/79600866此文代码注释写得特别好
//https://www.cnblogs.com/NaVi-Awson/p/7641892.html此文代码写得不错
/*
该题的核心是,二分 套牌数目,
计算出所需的 joker的个数,算出的 所需的 joker的个数 需小于等于提供的 joker的个数
因每副 套牌 只能用 1个joker,故算出的 所需的 joker的个数 需小于等于 二分中的 套牌数目

*/
//二分的判定过程,还是比较难想的.2019-8-23 8:29
//计算过程中,int容易溢出,不过,程序编得好,还是可以不涉及long long
//样例通过,提交Wrong_Answer.2019-8-13 8:42
//想了想,存在 套牌数目==0的情况,代码确实出了问题
/*
提供如下测试数据
3 0
0 2 3
输出为
0
*/
//left=0,right=m+1;//此处错写成left=1,right=m+1;
//修改,提交Wrong_Answer.2019-8-23 8:47
//仔细想想,还是处理过程中,存在误解,方案数可以大于 提供的 joker的个数,之前误以为是小于等于的关系
//0 < = m, ci < = 500,000,000,故最大方案数是500,000,000
//left=0,right=500000000+1;//此处错写成left=0,right=m+1;
//修改,提交Wrong_Answer.2019-8-23 9:04
//left=0,right=520000000;//left=0,right=500000000+1;
//将right=510000000提交Wrong_Answer
//将right=520000000提交AC
//不得不说后台的测试数据有误,因0 < = m, ci < = 500,000,000,故最大方案数 之可能 是500,000,000
//测试完毕,收工,以下为AC代码,收获是,数据还是要比条件提供的大许多,防止后台数据有误.2019-8-23 9:24
#include <stdio.h>
int n,m,c[55];
int judge(int x){//x指当前的套牌数目
    int i,tot=0;//tot指需要补的joker数量
    for(i=1;i<=n;i++)//选择不用那一种
        if(x>c[i]){
            tot+=x-c[i];//x>c[i]指当前i位置的牌数量不足,需要joker来补
            if(tot>m||tot>x)return 0;//在此判断的好处是可以回避long long//最多有m个joker,tot不能超越;因1套牌,最多只能用1个joker,故,用的joker数量必须 小于等于 套牌数目
        }
    return 1;
}
void bitsection(){
    int left,right,mid;
    left=0,right=520000000;//left=0,right=500000000+1;//此处错写成left=0,right=m+1;//此处错写成left=1,right=m+1;//right=m+1目的是使答案落在left,若无法理解,请拿出纸笔进行模拟
    while(left+1<right){
        mid=(left+right)/2;
        if(judge(mid)) left=mid;
        else right=mid;
    }
    printf("%d\n",left);
}
int main(){
    int i;
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++)scanf("%d",&c[i]);
    bitsection();
    return 0;
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值