THUPC_2017玩游戏Game题解

文章目录

    • 题目链接
    • 题意
    • 思路
    • 注意事项
    • 代码
  • Thanks!

题目链接

题意

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

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

思路

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

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

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

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

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

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

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

注意事项

∵   1 ≤ a , b ≤   2 31 − 1 \because\ 1\le a,b\le\ 2^{31} - 1  1a,b 2311

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

代码

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#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!

你可能感兴趣的:(c++)