Conquering Keokradong LightOJ 1048

一道lightoj 上的题目,我是在上次的一次练习赛中做到的,那时候两个半小时之后就只剩下两题了,而且两题原理是一样的,超开心,结果看了半个小时后这题,一句话:没思路。然后打酱油了。。。囧。

好吧,昨天学二分的时候突然思路来了,果断把那时候还有一题(LightOJ 1076 Get the Containers)给戳掉了。然后么,在这题的打印上又卡了好长时间,,,我好弱啊。。。囧。


好吧,思路就是二分:

//Danceonly

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>

using namespace std;

const int INF = 100000007;

#define MIN(a,b) (a > b ? b : a)
#define MAX(a,b) (a > b ? a : b)

int aa[10005];
int N,M;
bool Find(int x)
{
      int t = x;
      int cnt = 1;
      for (int i=0;i<N;i++)
      {
            if (x < aa[i])return 0;
            if (t - aa[i] >= 0)t -= aa[i];
            else {t = x - aa[i];if (++cnt > M)return 0;}
      }
      if (cnt <= M)return 1;
      else return 0;
}


void Print(int x)
{
      int cnt = 0;
      for (int i=0;i<N;i++)
      {
            if (aa[i]+aa[i+1] > x || N - i == M - cnt){printf("%d\n",aa[i]);cnt++;}
            else aa[i+1] += aa[i];
      }
}
int main()
{
      int T;
      scanf("%d",&T);
      for (int c=1;c<=T;c++)
      {
            int sum = 0;
            int max_n = 0;
            scanf("%d%d",&N,&M);
            N++; M++;
            for (int i=0;i<N;i++)
            {
                  scanf("%d",&aa[i]);
                  if (max_n < aa[i])max_n = aa[i];
                  sum += aa[i];
            }
            if (N == M)
            {
                  printf("Case %d: %d\n",c,max_n);
                  for (int i=0;i<N;i++)printf("%d\n",aa[i]);
                  continue;
            }
            int r = max_n;
            int l = sum;
            int mid;
            while (l - r >= 1)
            {
                  mid = (l+r)/2;
                  if (Find(mid))
                        l = mid;
                  else
                        r = mid + 1;
            }
            while (Find(mid) == 0)mid ++;
            printf("Case %d: %d\n",c,mid);
            Print(mid);
      }
      return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值