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;
    }
    

      

  • 相关阅读:
    5.0、Android Studio调试你的应用
    4.4、Android Studio在命令行运行Gradle
    4.3、Android Studio突破64K方法限制
    4.2、Android Studio压缩你的代码和资源
    4.1、Android Stuido配置你的Build Variant
    【java多线程系列】java中的volatile的内存语义
    【java多线程系列】java内存模型与指令重排序
    4.0、Android Studio配置你的构建
    HashMap
    zk常用命令
  • 原文地址:https://www.cnblogs.com/zufezzt/p/8080613.html
Copyright © 2011-2022 走看看