Codeforces Round 903 (Div. 3)
C
题意:
给你一个 n * n 的小写字母矩阵,如果矩阵逆时针旋转90°后与原矩阵相同那么成为完美矩阵
每次操作你可以把一个字符修改为它在字母表中的下一个(z保持不变),问最少操作多少次可以
变成完美矩阵
思路:
仔细观察发现旋转一次,每个点都有四个对应点,只要这四个点一样就行
inline void solve()
{
int n; cin >> n;
std::vector<string> s(n);
for (int i = 0; i < n; i++)
cin >> s[i];
LL ans = 0;
for (int i = 0; i < n / 2; i++)
for (int j = 0; j < n / 2; j++)
{
int sum = s[i][j] + s[j][n - i - 1] + s[n - i - 1][n - j - 1] + s[n - j - 1][i];
int maxx = max({s[i][j], s[j][n - i - 1], s[n - i - 1][n - j -1], s[n - j - 1][i]});
ans += maxx * 4 - sum;
}
cout << ans << endl;
}
D
题意:
给你一个由 n 个正整数组成的数组 a。你可以对它进行以下操作:
- 选择两个数a[i], a[j]并且 i != j
- 令 x 为a[i]的一个因数,让 a[i] = a[i] / x, a[j] = a[j] * x
问能不能通过多次上述操作让数组每个数都变得一样
思路:
观察操作我们可以发现本质就是将a[i]的因数转移到a[j]上,如果每个数相同那么每个数的因数也肯定相同
所以因数的个数一定要是n的倍数
inline void solve()
{
int n; cin >> n;
std::vector<int> a(n);
map<int, int> mp;
for (int i = 0; i < n; i++)
{
cin >> a[i];
for (int j = 2; j <= a[i] / j; j++)
{
if (a[i] % j == 0)
{
int cnt = 0;
while (a[i] % j == 0) a[i] /= j, cnt++;
mp[j] += cnt;
}
}
if (a[i] > 1) mp[a[i]]++;
}
for (auto [x, y] : mp)
{
if (y % n != 0)
{
cout << "No" << endl;
return;
}
}
cout << "Yes" << endl;
}
E:
题意:
给定一个长度为 n 的整数序列 a。如果一个序列是由一系列块组成的,每个块从它的长度开始,即首先是块的长度,然后是它的元素,那么这个序列就叫做美丽序列。例如,序列 [ 3, 3, 4, 5, 2, 6, 1]和 [ 1, 8, 4, 5, 2, 6, 1]是美丽的(不同的块的颜色不同),而 [ 1 ]、[ 1, 4, 3 ]、[ 3, 2, 1 ]则不是。
在一次操作中,你可以删除序列中的任何元素。要使给定的序列漂亮,最少需要多少次操作?
思路:
dp[i] : i ~ n最少需要的操作数
inline void solve()
{
int n; cin >> n;
std::vector<int> a(n + 1);
for (int i = 1; i <= n; i++)
cin >> a[i];
vector<int> f(n + 2, inf);
f[n + 1] = 0;
for (int i = n; i >= 1; i--)
{
f[i] = f[i + 1] + 1; // 删除a[i]
if (i + a[i] <= n) // 不删a[i], 那么后a[i]个数都得保留
f[i] = min(f[i], f[i + a[i] + 1]);
}
cout << f[1] << endl;
}

浙公网安备 33010602011771号