2008(970div3)
A. Sakurako's Exam
今天,樱子要参加数学考试。老师给出了由
在数组中,樱子必须在每个元素前面加上 "+"或"-",这样数组中所有元素的和就等于
樱子不确定是否有可能解决这个问题,那么请判断是否有办法分配符号,使数组中所有元素的和等于
void solve() {
int a, b;cin >> a >> b;
if (a & 1) {
cout << "NO\n";return;
}
if (b & 1) {
if (a) {
cout << "YES\n";
} else {
cout << "NO\n";
}
} else {
cout << "YES\n";
}
}
B. Square or Not
漂亮的二进制矩阵是指边缘为 1、内部为 0 的矩阵。
您需要检查得到字符串
void solve() {
int n;cin >> n;
string s;cin >> s;s = ' ' + s;
int m = n;
int idx = 0;
for (int i = 2;i <= n;i++) {
if (i * i == n) {
idx = i;break;
}
}
if (!idx) {
cout << "No\n";return;
}
int ok = 1;
for (int i = 1;i <= idx;i++) {
for (int j = 1;j <= idx;j++) {
int p = (i - 1) * idx + j;
if (i == 1 || j == 1 || i == idx || j == idx) {
if (s[p] != '1')ok = 0;
} else {
if (s[p] == '1')ok = 0;
}
}
}
if (ok) {
cout << "Yes\n";
} else {
cout << "No\n";
}
}
C. Longest Good Array
今天,樱子在学习数组。长度为
- 数组
是递增的,即所有 都是 ; - 相邻元素之间的差值是递增的,即所有
的差值为 。
樱子想到了边界
请帮助樱子找出给定的
void solve() {
int l, r;cin >> l >> r;
int cnt = 0, x = 0;
for (int i = l;i <= r;i += x) {
x++;cnt++;
}
cout << cnt << '\n';
}
D. Sakurako's Hobby
对于某个排列
如果是
排列中的每个数字都被染成黑色或白色。
樱子将函数
樱子对每个
void solve() {
int n;cin >> n;
vector<int> p(n + 1), q(n + 1);
for (int i = 1;i <= n;i++)cin >> p[i], q[p[i]] = i;
string s;cin >> s;s = ' ' + s;
vector<int> ans(n + 1), vis(n + 1);
int m = 0;
auto dfs = [&](auto self, int x, int y)->void {
if (vis[x])return;
m++;
vis[x] = 1;
if (s[x] == '1')m--;
self(self, y, p[y]);
ans[x] = m;
};
for (int i = 1;i <= n;i++) {
m = 0;
if (!vis[i] && s[i] == '0') {
dfs(dfs, i, p[i]);
}
}
for (int i = 1;i <= n;i++) {
cout << ans[i] << " \n"[i == n];
}
}
F. Sakurako's Box
樱子有一个装有
计算其期望值
#define int long long
constexpr int mod = 1e9 + 7;
void solve() {
int n;cin >> n;
vector<int> a(n + 1), pre(n + 1);
for (int i = 1;i <= n;i++)cin >> a[i];
for (int i = 1;i <= n;i++) {
pre[i] = pre[i - 1] + a[i];
}
int ans = 0;
for (int i = 1;i < n;i++) {
int p = (pre[n] - pre[i]) % mod * a[i] % mod;
int q = n * (n - 1) / 2;q %= mod;
ans += p * inv(q) % mod;ans %= mod;
}
cout << ans << '\n';
}
E. Alternating String
樱子非常喜欢交替字符串。如果满足
- 偶数位置上的字符相同
- 奇数位置上的字符相同
- 字符串的长度是偶数
她就会把由拉丁小写字母组成的字符串
作为好朋友,您决定赠送这样的字符串,但您找不到。幸运的是,您可以对字符串进行两种操作:
- 选择索引
并删除字符串中的 -th 字符,这样字符串的长度就会减少 。此类操作的**次数不超过 次; - 选择索引
并将 替换为任何其他字母。
由于时间紧迫,您需要确定使字符串成为交替字符串所需的最少操作次数。
Solution
看了题解,感觉和我之前的想法是一样的,不知道哪里出了问题。
这里是从最后一个位置开始,开始慢慢往前推,(刚开始是将最后一位删除掉,然后后面开始交替操作,将最后一位加回来,将当前位删掉),通过这种方式可以完成所有可能。(Effective Code!)
#define all(a) a.begin(), a.end()
void solve() {
int n;cin >> n;
string s;cin >> s;
vector<vector<int>> cnt(2, vector <int>(26));
for (int i = 0; i < n; ++i) {
cnt[i & 1][s[i] - 'a']++;
}
if (n & 1 ^ 1) {
cout << n - *max_element(all(cnt[0])) - *max_element(all(cnt[1])) << '\n';
return;
}
cnt[n - 1 & 1][s[n - 1] - 'a']--;
int ans = *max_element(all(cnt[0])) + *max_element(all(cnt[1]));
for (int i = n - 2; i >= 0; i--) {
cnt[i & 1][s[i] - 'a']--;
cnt[i & 1][s[i + 1] - 'a']++;
ans = max(ans, *max_element(all(cnt[0])) + *max_element(all(cnt[1])));
}
cout << n - ans << '\n';
}
G. Sakurako's Task
樱子为你准备了一项任务:
她给了你一个由
樱子问你,数组的
Solution
- 需要证明: 根据操作,可以得到最终的的数组是
- 得到了这个数组,如何以一种较快的方式求出
最终能凑出来的是
在每个间隔有
如果大于了这个数,说明已经超出了
即
按照这种方式来求
#define int long long
void solve() {
int n, k;cin >> n >> k;
vector<int> a(n + 1);
for (int i = 1;i <= n;i++)cin >> a[i];
int g = a[1];
for (int i = 1;i <= n;i++)g = __gcd(g, a[i]);
if (n == 1) {
cout << (a[1] >= k ? k - 1 : k) << '\n';return;
}
int t = (g - 1) * (n - 1);
if (k > t) {
cout << n - 1 + k << '\n';
} else {
if (k % (g - 1) == 0) {
cout << k / (g - 1) * g - 1 << '\n';
} else {
cout << k / (g - 1) * g + k % (g - 1) << '\n';
}
}
}
H. Sakurako's Test
樱子即将参加一项测试。测试可以描述为一个整数数组
给定一个整数
- 选择一个整数
( ),使得 ; - 将
的值改为 。
任意多次使用此操作,她必须找出数组
樱子知道数组,但不知道整数
Solution
调和级数复杂度<->mod Q
根据贪心的思想,
提前预处理出
可以二分答案(对于
时间复杂度:
void solve() {
int n, q;cin >> n >> q;
vector<int> mp(n + 1);
for (int i = 1;i <= n;i++) {
int x;cin >> x;mp[x]++;
}
for (int i = 1;i <= n;i++)mp[i] += mp[i - 1];
vector<int> ans(n + 1);
for (int i = 1;i <= n;i++) {//x
int l = 0, r = i - 1;
while (l < r) {
int mid = l + r >> 1;
int s = 0;
for (int j = 0;j <= n;j += i) {
s += mp[min(n, j + mid)] - (j == 0 ? 0 : mp[j - 1]);
}
if (s >= n / 2 + 1) {
r = mid;
} else {
l = mid + 1;
}
}
ans[i] = l;
}
while (q--) {
int x;cin >> x;
cout << ans[x] << ' ';
}
cout << '\n';
}