THUPC_2017玩游戏Game题解

题目链接

题意

j z m jzm 和他的学妹在玩游戏,这个游戏共有 n n 轮,在第 i i 轮获胜会获得 i i 分,没有平局。

现在给出 j z m jzm 和学妹的得分,求是否有一种方案符合当前得分。

思路

首先我们可以知道,学妹和 j z m jzm 的分数之和一定是一个可以表示为 n ( n + 1 ) 2 \frac{n(n+1)}{2}的数

对于如何查找,因为 n n 只有 1 e 5 1e5 ,故我们可以使用暴力来查找

当然,也可以通过二分来查找 (提升不明显)

若是找不到这样的一个 n n ,就可以直接输出 N o No

接着我们考虑如何求出答案:

有一个显而易见的结论, 1 1 ~ n n 中任意取,可以取出 1 1 ~ n ( n + 1 ) 2 \frac{n(n+1)}{2} 中的所有数字

有了这个结论,我们就可以直接从大往小取,取到 a a 被取没了,就ok了

注意事项

  1 a , b   2 31 1 \because\ 1\le a,b\le\ 2^{31} - 1

  a , b \therefore\ a, b 都应该开 l o n g   l o n g long\ long

代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cctype>
#include <map>
#include <set>
#include <vector>
#include <iostream>
#include <cmath>
#define pk putchar(' ')
#define ph puts("")
#pragma GCC optimize(2)
using namespace std;
typedef long long ll;
template <class T>
void rd(T &x)
{
    x = 0;
    int f = 1;
    char c = getchar();
    while (!isdigit(c)) {if (c == '-') f = -1; c = getchar();}
    while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
    x *= f;
}
template <class T>
void pt(T x)
{
    if (x < 0)
        putchar('-'), x = (~x) + 1;
    if (x > 9)
        pt(x / 10);
    putchar(x % 10 ^ 48);
}
template <class T>
T Max(T a, T b)
{
    return a > b ? a : b;
}
template <class T>
T Min(T a, T b)
{
    return a < b ? a : b;
}
const int N = 1e5 + 5;
ll a, b;
int main() 
{
    rd(a), rd(b);
    b += a;
    ll l = 0, r = 1e5;
    while (l <= r)
    {
        ll mid = (l + r) >> 1, res = mid * (mid + 1) / 2;
        if (res < b)
            l = mid + 1;
        else if (res > b)
            r = mid - 1;
        else
        {
            l = mid;
            break;
        }
    }
    if (l * (l + 1) / 2 != b)
    {
        puts("No");
        return 0;
    }
    pt(l);
    for (int i = l;i && a; i--)
        if (a >= i)
        {
            a -= i;
            pk;
            pt(i);
        }
    return 0;
}

Thanks!

原创文章 23 获赞 41 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43537070/article/details/103325073