https://www.acmicpc.net/problem/12966
이 포스트는 12934 - 턴 게임으로부터 얻을 수 있는 통찰을 포함하여 설명하도록 한다.
등차수열로의 전환과 등차수열의 합
$i$턴에 이긴 사람은 $2 \times i - 1$ 점으로, 이는 모두 홀수이다.
초항을 $a$, 공차를 $d$인 등차수열로 표현할 때, 등차수열의 합은 $S_{n} = \frac{n}{2}(2a + (n - 1)d)$이고,
$a = 1, d = 2$이므로 $S_{n} = \frac{n}{2}(2 \times 1 + (n - 1) \times 2)$ = $n^{2}$이다.
따라서, $x + y$는 제곱수가 되어야 한다. $x + y$가 제곱수가 아니라면, 나올 수 없는 경우니 답은 $-1$이다.
문제를 $k$ 찾기로 전환하기
윤호가 $k$번 이긴다고 할 때, $i$를 각각 이긴 턴의 원소라고 하면 윤호가 이긴 턴의 집합 $S$에서 $i \in S$ 관계를 갖게 된다.
그러면
$$x = \sum_{i \in S}(2i - 1) = 2 \sum_{i \in S}i - k$$
로 나타낼 수 있다.
따라서,
$$Z = \frac{x + k}{2} = \sum_{i \in S}i$$
로 식을 정리할 수 있고, 식을 만족하는 $min(k)$를 찾는 문제로 전환할 수 있다.
$Z$가 가능한 부등식 찾기
그런데, $k$개의 수를 뽑는다고 하면 여기서 나타날 수 있는 합의 최소와 최대가 있다.
합의 최솟값
1부터 $k$까지의 합을 구한다면 $\frac{k(1 + k)}{2}$로, $k$개의 수를 더한 합의 최소가 된다.
합의 최댓값
$n$부터 1씩 감소하여 연속된 $k$개의 정수의 합을 구한다면 $nk - \frac{(k - 1)(1 + (k - 1))}{2} = \frac{k(2n - k + 1)}{2}$가 합의 최대가 된다.
따라서, $Z$가 가능한 합이 되려면 다음 부등식을 만족해야 한다.
$$ \frac{k(1 + k)}{2} \leq Z \leq \frac{k(2n - k + 1)}{2} $$
1부터 $n$까지 모든 $k$에 대해, $x$와 $k$의 패리티가 동일하며, 위 부등식을 만족하는 $min(k)$ 혹은 -1을 출력하면 된다.
전체 코드 - CPP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
#pragma GCC target("avx,avx2,fma,bmi,bmi2,lzcnt,popcnt")
#pragma GCC optimize("O3,unroll-loops")
#include "bits/stdc++.h"
#include "ext/pb_ds/assoc_container.hpp"
using namespace std;
using namespace __gnu_pbds;
using pii = pair<int, int>;
using ll = int_fast64_t;
ll is_square(ll val)
{
ll lo = 0, hi = 1 + sqrt(val);
while (lo <= hi)
{
ll mid = lo + (hi - lo) / 2;
if (mid * mid == val) return mid;
if (mid * mid < val)
{
lo = mid + 1;
}
else
{
hi = mid - 1;
}
}
return -1;
}
void solve()
{
ll a, b;
cin >> a >> b;
ll sum = a + b;
auto n = is_square(sum);
if (n == -1)
{
cout << -1;
return;
}
if (a == 0)
{
cout << 0;
return;
}
for (int i = 1; i <= n; i++)
{
if ((i & 1) != (a & 1))
{
continue;
}
ll t = (a + i) / 2;
ll l_val = (ll)i * (i + 1) / 2;
ll r_val = (ll)i * (2 * n + 1 - i) / 2;
if (l_val <= t and t <= r_val)
{
cout << i;
return;
}
}
cout << -1;
}
int main()
{
#ifdef LOCAL
// freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
ios::sync_with_stdio(false);
cin.tie(nullptr);
solve();
}
|
cs |
'백준 > 수학' 카테고리의 다른 글
백준 12116 - Uzastopni (0) | 2025.03.31 |
---|---|
백준 2378 - 불필요한 수 (0) | 2025.01.29 |
백준 12994 - 이동 3-2 (0) | 2025.01.22 |
백준 31002 - 그래프 변환 (0) | 2025.01.11 |
[ICPC] 백준 28152 - Power of Divisors (0) | 2024.11.27 |