VP Educational Codeforces Round 11
A. Co-prime Array time limit per test1 second
题意:给你一个数组,你要插入尽可能少的数,使得任意两个相邻的数都互质。
如果相邻两个不互质,就插入一个1即可。
点击查看代码
void solve() {
int n;
std::cin >> n;
std::vector<int> a(n);
for (int i = 0; i < n; ++ i) {
std::cin >> a[i];
}
std::vector<int> ans{a[0]};
for (int i = 1; i < n; ++ i) {
if (std::gcd(ans.back(), a[i]) != 1) {
ans.push_back(1);
}
ans.push_back(a[i]);
}
std::cout << (int)ans.size() - n << "\n";
for (auto & x : ans) {
std::cout << x << " ";
}
std::cout << "\n";
}
B. Seating On Bus
按题意模拟。
点击查看代码
void solve() {
int n, m;
std::cin >> n >> m;
std::vector a(n, std::vector<int>(4, -1));
int k = 0;
for (int i = 0; i < n && k < m; ++ i) {
a[i][0] = k ++ ;
if (k < m) {
a[i][3] = k ++ ;
}
}
for (int i = 0; i < n && k < m; ++ i) {
a[i][1] = k ++ ;
if (k < m) {
a[i][2] = k ++ ;
}
}
std::vector<int> ans;
for (int i = 0; i < n; ++ i) {
if (a[i][1] != -1) {
ans.push_back(a[i][1]);
}
if (a[i][0] != -1) {
ans.push_back(a[i][0]);
}
if (a[i][2] != -1) {
ans.push_back(a[i][2]);
}
if (a[i][3] != -1) {
ans.push_back(a[i][3]);
}
}
for (int i = 0; i < m; ++ i) {
std::cout << ans[i] + 1 << " \n"[i == m - 1];
}
}
C. Hard Process
题意:给你一个01序列,你可以改\(k\)个0为1,求最长的连续1区间的长度。
我们的\(k\)的1肯定要和其他1贴在一起,最后要让所有新加的1都在一个连续段里。所以我们对于每个位置可以二分以它开头的连续1可以延长到的位置,就是看[i, mid]里0的数量是不是小于等于\(k\)就行了。
点击查看代码
void solve() {
int n, k;
std::cin >> n >> k;
std::vector<int> a(n);
for (int i = 0; i < n; ++ i) {
std::cin >> a[i];
}
std::vector<int> sum(n + 1);
for (int i = 0; i < n; ++ i) {
sum[i + 1] = sum[i] + a[i];
}
int ans = 0, p = 1;
for (int i = 1; i <= n; ++ i) {
int l = i, r = n;
while (l < r) {
int mid = l + r + 1 >> 1;
if (mid - i + 1 - (sum[mid] - sum[i - 1]) <= k) {
l = mid;
} else {
r = mid - 1;
}
}
if (l - i + 1 - (sum[l] - sum[i - 1]) <= k && l - i + 1 > ans) {
ans = l - i + 1;
p = i;
}
}
for (int i = p; i < p + ans; ++ i) {
a[i - 1] = 1;
}
std::cout << ans << "\n";
for (int i = 0; i < n; ++ i) {
std::cout << a[i] << " \n"[i == n - 1];
}
}
D. Number of Parallelograms
题意:给你\(n\)个点,求有多少点可以组成平行四边形。
平行四边形的两个对角线的交点平分两条对角线,那么可以枚举作为对角线的两个点,求出中点,看有多少点对的中点相同,那么答案就是所有中点相同的点对里选两个的方案。
点击查看代码
void solve() {
int n;
std::cin >> n;
std::vector<std::pair<int, int>> a(n);
for (int i = 0; i < n; ++ i) {
std::cin >> a[i].first >> a[i].second;
}
std::map<std::pair<int, int>, int> cnt;
for (int i = 0; i < n; ++ i) {
for (int j = i + 1; j < n; ++ j) {
cnt[{a[i].first + a[j].first, a[i].second + a[j].second}] += 1;
}
}
i64 ans = 0;
for (auto & [it, x] : cnt) {
ans += (i64)x * (x - 1) / 2;
}
std::cout << ans << "\n";
}
E. Different Subsets For All Tuples
待补。

浙公网安备 33010602011771号