传送门 Educational Codeforces Round 99 (Rated for Div. 2)
A
g ( x ) g(x) g(x) 的值域为 1 0 n , n ∈ Z 10^n,n\in Z 10n,n∈Z,答案即数位个数。
#include <bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin >> t;
while (t--)
{
string s;
cin >> s;
cout << s.length() << endl;
}
return 0;
}
B
目标是使步数最小,那么至少需要走 n n n 步, n n n 是满足 ( n + 1 ) × n / 2 ≥ x (n+1)\times n/2\geq x (n+1)×n/2≥x 的最小值。接着考虑走 − 1 -1 −1 步的情况,将 [ 1 , n ] [1,n] [1,n] 步中任一步替换为 − 1 -1 −1,可以从 ( n + 1 ) × n / 2 ≥ x (n+1)\times n/2\geq x (n+1)×n/2≥x 减去的值范围为 [ 2 , n + 1 ] [2,n+1] [2,n+1],而 ( n + 1 ) × n / 2 − x (n+1)\times n/2-x (n+1)×n/2−x 值域为 [ 0 , n ) [0,n) [0,n);那么对于 ( n + 1 ) × n / 2 − x = 1 (n+1)\times n/2-x=1 (n+1)×n/2−x=1 的情况,需要多花费一个步骤走 − 1 -1 −1 的距离,对于其他情况直接从 [ 1 , n ] [1,n] [1,n] 步中取距离等于 ( n + 1 ) × n / 2 − x − 1 (n+1)\times n/2-x-1 (n+1)×n/2−x−1 的那一步替换为走 − 1 -1 −1 的距离。
#include <bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin >> t;
while (t--)
{
int x;
cin >> x;
int lb = 0, ub = 2005;
while (ub - lb > 1)
{
int mid = (ub + lb) >> 1;
int t = ((mid + 1) * mid) >> 1;
if (t < x)
lb = mid;
else
ub = mid;
}
int m = ((1 + ub) * ub) >> 1;
if (m - x == 1)
++ub;
cout << ub << endl;
}
return 0;
}
C
双方以自己取胜为第一优先级。考虑到先手必须损耗一点耐力,若轮到某一方先手,后手方不断认输,即可达到先手方耐力消耗殆尽的局面,此时后手方能取得的最大胜利数是自己的耐力值;在这个策略下使自己失败数最小,那么在对手剩最后一点耐力值时选择反击即可。最终 A l i c e Alice Alice 获胜 x − 1 x-1 x−1 次, B o b Bob Bob 获胜 y y y 次。
#include <bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin >> t;
while (t--)
{
int x, y;
cin >> x >> y;
cout << x - 1 << ' ' << y << endl;
}
return 0;
}
D
可以观察到 x x x 单调递增, a i a_i ai 替换后单调递减。考虑如何进行交换,假设当前未达到有序状态,则存在位置 i i i,满足 a [ i ] > a [ i + 1 ] a[i]>a[i+1] a[i]>a[i+1]。若先替换 j , j > i j,j>i j,j>i 的位置,那么替换 i i i 位置时的 x x x 大于替换 j j j 位置时的值,此时 a i > a j , i < j a_i>a_j,i<j ai>aj,i<j 显然不满足有序,于是有推论:从左向右按顺序替换才能到达数列有序的局面。
假设替换了 a i a_i ai,可能出现 a i − 1 > a i a_{i-1}>a_i ai−1>ai 的情况,那么可能需要预先替换 k , k < i k,k<i k,k<i 位置才能到达有序的局面,问题在于如何选择替换位置。出现 a i − 1 > a i a_{i-1}>a_i ai−1>ai 的情况原因是 a i − 1 > x a_{i-1}>x ai−1>x,于是得到替换策略:从左向右按顺序替换满足 a i > x a_i>x ai>x 的位置 i i i 才能到达数列有序的局面。
目标是替换次数最少,那么替换结束后检查后续位置,若已经满足有序性,则结束替换过程。总的时间复杂度 O ( n 2 ) O(n^2) O(n2)。
#include <bits/stdc++.h>
using namespace std;
bool judge(int l, int r, int *a)
{
bool f = 1;
for (int i = l + 1; i < r; ++i)
if (a[i - 1] > a[i])
{
f = 0;
break;
}
return f;
}
int main()
{
int t, n, x, a[505];
cin >> t;
while (t--)
{
cin >> n >> x;
for (int i = 0; i < n; ++i)
cin >> a[i];
if (judge(0, n, a))
{
cout << 0 << endl;
continue;
}
int res = INT_MAX;
bool f = 1;
int step = 0;
for (int i = 0; i < n; ++i)
{
if (a[i] > x)
++step, swap(a[i], x);
if (i > 0 && a[i - 1] > a[i])
{
f = 0;
break;
}
if (judge(i, n, a))
break;
}
if (f)
res = min(res, step);
cout << (res == INT_MAX ? -1 : res) << endl;
}
return 0;
}