zoukankan      html  css  js  c++  java
  • FZYZOJ-1880 【UFO】水管

    P1880 -- 【ufo】水管

    时间限制:1000MS      内存限制:131072KB      通过/提交人数:32/100

    状态:      标签:    数学问题-组合数学   无   无

    Description

    lzl:我最近买了一套面积2147483647的房子,可是黄地产开发商sxbk,竟然只给我装了一根水管。

    ufo:还不够么?

    lzl:鉴于我的增肥计划,我需要n个厨房,每个厨房至少得有1根水管接入吧。

    ufo:。。。不要急,你看我给你送来了神奇的水管转换器,可以使水管1变x。

    ufo拥有1变2至1变k的转换器各一个,问至少要几个转换器才能满足lzl的增肥需求。

    下图是1变4的转换器示意图

    器

    Input Format

    两个整数n,k

    Output Format

    满足lzl需求需要用到转换器最少个数,不能满足的输出-1

    Sample Input

    4 3

    Sample Output

    2

    Hint

    对于30%的数据1 ≤ n ≤ 10, 2 ≤ k ≤ 10

    对于100%的数据1 ≤ n ≤ 10^18, 2 ≤ k ≤ 10^9

    ufo:黄地产给你装下水管没?

    lzl:没。。没事,大肚能容天下事   嗝~~~

     

    题解

          根据贪心的思想,必须从大到小选用转换器才能得到最优解。不难发现,在这个选用的过程中,每次增加的水管数量构成等差数列,那么可以运用等差数列求和公式。

          方法一:在[1,k]中二分答案,用等差数列求和公式判定得到最优解。

          方法二:由等差数列求和公式得到一元二次方程,解方程。

    代码

     1 #include <cstdio>
     2 #include <iostream>
     3 using namespace std;
     4 
     5 long long N, K;
     6 long long L, R;
     7 
     8 double Calc(long long K, long long N) {
     9     N = N - 1;
    10     return (double) (K - 0.5) * N - 0.5 * N * N + 1;
    11 }
    12 
    13 int main() {
    14     scanf("%lld%lld", &N, &K);
    15     if (Calc(K, K) < N) {
    16         printf("-1
    ");
    17         return 0;
    18     }
    19     L = 1;
    20     R = K;
    21     while (L <= R) {
    22         long long Mid = (L + R) >> 1;
    23         double Sum = Calc(K, Mid);
    24         if (Sum < N) L = Mid + 1;
    25         else R = Mid - 1;
    26     }
    27     printf("%lld
    ", L - 1);
    28 }
  • 相关阅读:
    java.util.ConcurrentModificationException故障分析
    Eclipse常见问题总结-持续更新
    MySQL学习—简单存储过程
    Mysql学习——触发器
    MySQL学习—多表查询(内连接,外链接,全连接)
    JDK环境变量配置
    Spring学习总结(二)——容器对Bean的管理
    Spring学习总结(一)——Spring容器的实例化
    类加载机制
    手写数据库连接池
  • 原文地址:https://www.cnblogs.com/DonMaestro/p/4324191.html
Copyright © 2011-2022 走看看