zoukankan      html  css  js  c++  java
  • 2017年浙江中医药大学大学生程序设计竞赛(重现赛)B

    题目描述

    大家都知道Alice和Bob两个人是一生之敌。(雾  
    但某天,他们两个人发了疯。想知道他们两个是否可以成为朋友。  
    于是他们做了一个令人窒息的决定。    
    Alice和Bob每个人任意选一个整数。  
    假设Alice选择了整数a,Bob选择了整数b。  
    Alice使得a做如下变换:  
    a -> 2 * a * (a+1)^2
    Bob使得b做如下变换:  
    b -> b^2
    如果变换后的数字相等,则两个人可以化敌为友。  
    如果不相等,这两个人怕是石乐志。
    现在,你想把Bob部分可能的整数b(存在a变换后的数字等于b变换后的数字)从小到大排列后,知道第一个大于等于n的数字是多少。
     
     

    输入描述:

    第一行输入一个整数T,表示数据组数。
    每组数据输入一个整数n。
    1 <= T <= 100000
    0 <= n <= 10^19
    保证结果存在

    输出描述:

    输出一个整数。
    示例1

    输入

    3  
    2  
    6  
    100

    输出

    6
    6
    114

    题解

    二分查找。

    要使得$ b^2 = 2 * a * (a+1)^2$,即$b= sqrt{2 * a * (a+1)^2}$。

    因为$b$是整数,所以`$sqrt{2 * a * (a+1)^2}$`也是整数,因此$sqrt{2 * a}$为整数。

    设$p$为整数,则$a$可以表示为$a = 2*p*p$,则$b = 2*p*(2*p*p+1)$,因此二分$p$就可以得到答案了。

    最后注意一下溢出的问题。

    #include <bits/stdc++.h>
    using namespace std;
    
    int T;
    
    int main() {
      scanf("%d", &T);
      while(T --) {
        unsigned long long n;
        scanf("%llu", &n);
        if(n == 0) {
          printf("0
    ");
          continue;
        }
        unsigned long long L = 0;
        unsigned long long R = 3e6;
        unsigned long long ans;
        while(L <= R) {
          unsigned long long mid = (L + R) / 2;
          unsigned long long p = mid * mid * mid * 4LL + mid * 2LL;
          if(p >= n) {
            ans = p;
            R = mid - 1;
          } else {
            L = mid + 1;
          }
        }
        printf("%llu
    ", ans);
      }
      return 0;
    }
    

      

  • 相关阅读:
    86. Partition List
    2. Add Two Numbers
    55. Jump Game
    70. Climbing Stairs
    53. Maximum Subarray
    64. Minimum Path Sum
    122. Best Time to Buy and Sell Stock II
    以场景为中心的产品设计方法
    那些产品经理犯过最大的错
    Axure教程:如何使用动态面板?动态面板功能详解
  • 原文地址:https://www.cnblogs.com/zufezzt/p/8080613.html
Copyright © 2011-2022 走看看