51nod

 题目链接 : 1390 游戏得分

思路:很容易证明合法的总分是n^2。那么n就是游戏的回合数。那么总的回合数最多就是sqrt(2e12)。然后求A最少胜几盘相当于B最多胜几盘。假设B总是在低回合中胜出,那么同样的分数,他能胜的盘数更多。于是假设B从第一局就开始胜,这样贪心去取分数,就能求出B最多能胜几盘。值得注意的是,B胜的回合数跟B的分数应该是同奇偶的。最后特判一下2分的情况,在这个游戏中,这个分数不可能出现。

复杂度分析:我先预处理出所有的B的情况,1e6,然后再二分查找,总的复杂度为 O(T*sqrt(x+y)log(sqrt(x+y)))。 最后发现太傻逼了,直接sqrt(b)不就好了么。。。。对的,最后复杂度为O(T*log(sqrt(x+y)))。【O(log(sqrt(x+y))) 为求开根号的复杂度】

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long ll;
 5 //const ll maxn = 1e12 + 100;
 6 // std::vector<ll> sq;
 7 // void init() {
 8 //     for(int i=0; i<1414215; i++) {
 9 //         sq.push_back(1LL*i*i);
10 //     }
11 // }
12 int main() {
13     //init();
14     int T;
15     scanf("%d", &T);
16     while(T--) {
17         ll a, b;
18         scanf("%lld%lld", &a, &b);
19         ll s = sqrt(a+b+0.5);
20         if(s*s != a+b) printf("-1
");
21         else if(a==2 || b==2) printf("-1
");
22         else {
23             // int l = lower_bound(sq.begin(), sq.end(), b) - sq.begin();
24             // if(sq[l] != b) {
25             //     l --;
26             //     l -= (b+l)&1;
27             // }
28             int l = sqrt(b+0.5);
29             l -= (b+l)&1;
30             printf("%lld
", s - l);
31         }
32     }
33     return 0;
34 }
原文地址:https://www.cnblogs.com/fredy/p/5871785.html