一生之敵-2017浙江中醫藥大學程式設計
阿新 • • 發佈:2019-01-27
時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 131072K,其他語言262144K
於是他們做了一個令人窒息的決定。
Alice和Bob每個人任意選一個整數。
假設Alice選擇了整數a,Bob選擇了整數b。
Alice使得a做如下變換:
a -> 2 * a * (a+1)^2
Bob使得b做如下變換:
b -> b^2
如果變換後的數字相等,則兩個人可以化敵為友。
如果不相等,這兩個人怕是石樂志。
現在,你想把Bob部分可能的整數b(存在a變換後的數字等於b變換後的數字)從小到大排列後,知道第一個大於等於n的數字是多少。
空間限制:C/C++ 131072K,其他語言262144K
64bit IO Format: %lld
題目描述
大家都知道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
這道題當時讀了很久,一直搞不懂樣例是怎麼出來,還是做的題少,沒有語感,中文題目都這樣了,何況英文題;
讀懂題意之後,一看資料範圍就知道是二分查詢,只需要把a和b做一下變換即可:
b^2 = 2*a*(a+1)^2 -> b = sqrt(2*a)*(a+1);
因為sqrt(2*a)是整數,所以令2*a=4*t*t,所以a=2*t*t;
所以就轉換成b=2*t*(2*t*t + 1),所以只需二分
#include <stdio.h> #include <iostream> using namespace std; #define MAX 3e6 typedef unsigned long long ULL; int main() { int T; cin>>T; while(T--) { ULL n; scanf("%llu",&n); if(n == 0) { printf("0\n"); continue; } ULL l = 0, r = MAX, m, t, ans; while(l <= r) { m = l+(r-l)/2; t = 4*m*m*m + 2*m; if(t >= n) { ans = t; r = m - 1; } else { l = m + 1; } } printf("%llu\n",ans); } return 0; }