codeforces1013D(模拟,并查集)

本文介绍了一种使用并查集数据结构解决n*m区域中所有格子被标记覆盖的算法。通过优化放置标记的位置,可以实现用最少的标记数达到完全覆盖的目标。文章详细解释了并查集的实现过程及如何利用它来减少重复标记,从而得到最优解。

题目:给你n*m的区域,q个格子放上了标记,如上图放了(r1,c1),(r1,c2),(r2,c1)后(r2,c2)就可以自动出来标记,问让最后所有的格子都被标记还需要的最小标记数。

思路:假设没有一个格子放有标记。下图还需放n+m-1个标记,能把所有的格子标记完。此时是最优的

然后把q个多放的格子放进去等效替换就可以啦,并查集去重。

#include <bits/stdc++.h>
using namespace std;
const int maxn=4e5+100;
int n,m,q,fa[maxn];
int findfa(int x)
{
    if(x==fa[x])return x;
    int y=x,tmp;
    while(x!=fa[x]) x=fa[x];
    while(fa[y]!=x)
    {
        int tmp=fa[y];
        fa[y]=x;
        y=tmp;
    }
    return x;
}
int main()
{
    scanf("%d%d%d",&n,&m,&q);
    for(int i=1;i<=n+m;i++)
        fa[i]=i;
    int ans=n+m-1;
    while(q--)
    {
        int x,y,fx,fy;
        scanf("%d%d",&x,&y);
        y+=n;
        fx=findfa(x);
        fy=findfa(y);
        if(fx!=fy)
        {
            fa[fx]=fy;
            ans--;
        }
    }
    printf("%d\n",ans);
    return 0;
}

 

目前尚未找到关于 Codeforces Round 1022 Div. 2 的具体题目及解析的相关资料。以下是基于已知信息和常见比赛题型的推测与解答框架: --- ### 常见 Codeforces 比赛题型分析 #### **A 类问题** 通常涉及简单的数学计算或逻辑判断,例如模拟操作、条件分支等。 **示例代码模板:** ```cpp #include <bits/stdc++.h> using namespace std; void solve() { int n; cin >> n; // 简单逻辑处理 if (n % 2 == 0) { cout << "Even\n"; } else { cout << "Odd\n"; } } signed main() { ios::sync_with_stdio(false); cin.tie(0); int t = 1; cin >> t; while (t--) { solve(); } } ``` 此类问题可能类似于引用中的简单逻辑推导[^4]。 --- #### **B 类问题** 一般需要一定的算法基础,比如贪心策略或者前缀/后缀数组的应用。 **示例代码模板:** ```cpp #include <bits/stdc++.h> using namespace std; const int MAXN = 1e5 + 5; long long pref_sum[MAXN]; void preprocess(vector<int> &arr, int n) { pref_sum[0] = arr[0]; for (int i = 1; i < n; ++i) { pref_sum[i] = pref_sum[i - 1] + arr[i]; } } void solve() { int n, q; cin >> n >> q; vector<int> arr(n); for (auto &x : arr) cin >> x; preprocess(arr, n); while (q--) { int l, r; cin >> l >> r; --l; --r; // 转化为0-based索引 long long res = pref_sum[r] - (l ? pref_sum[l - 1] : 0); cout << res << "\n"; } } signed main() { ios::sync_with_stdio(false); cin.tie(0); int t = 1; cin >> t; while (t--) { solve(); } } ``` 此部分可以参考 ST 表构建的思想[^1],适用于区间查询优化场景。 --- #### **C/D/E/F 类问题** 这些难度较高的题目往往涉及复杂的数据结构或高级算法,如动态规划、二分查找、并查集、最短路径等。 **E 类问题示例(矩阵最大值):** 给定一个 `n × m` 的网格以及若干点的高度值,要求找出某个子区域内的最大高度之和。 **解决方案思路:** 可以通过滑动窗口技术预处理二维前缀和,从而快速获取任意子矩形范围内的总和。 **代码实现:** ```cpp #include <bits/stdc++.h> using namespace std; const int MAXN = 2005; long long grid_sum[MAXN][MAXN]; // 预处理二维前缀和 void build_prefix(int n, int m, vector<vector<long long>> &grid) { for (int i = 1; i <= n; ++i) { for (int j = 1; j <= m; ++j) { grid_sum[i][j] = grid[i - 1][j - 1] + grid_sum[i - 1][j] + grid_sum[i][j - 1] - grid_sum[i - 1][j - 1]; } } } long long query(int x1, int y1, int x2, int y2) { return grid_sum[x2][y2] - grid_sum[x1 - 1][y2] - grid_sum[x2][y1 - 1] + grid_sum[x1 - 1][y1 - 1]; } void solve() { int n, m, g, k; cin >> n >> m >> g >> k; vector<pair<int, pair<int, int>>> gorillas(g); for (int i = 0; i < g; ++i) { cin >> gorillas[i].second.first >> gorillas[i].second.second >> gorillas[i].first; } sort(gorillas.begin(), gorillas.end(), [&](pair<int, pair<int, int>> a, pair<int, pair<int, int>> b) -> bool { return a.first > b.first; }); vector<vector<long long>> grid(n, vector<long long>(m, 0)); for (auto &[height, pos] : gorillas) { grid[pos.first - 1][pos.second - 1] = height; } build_prefix(n, m, grid); long long max_sum = 0; for (int i = 1; i + k - 1 <= n; ++i) { for (int j = 1; j + k - 1 <= m; ++j) { max_sum = max(max_sum, query(i, j, i + k - 1, j + k - 1)); } } cout << max_sum << "\n"; } signed main() { ios::sync_with_stdio(false); cin.tie(0); int t = 1; cin >> t; while (t--) { solve(); } } ``` 该方法借鉴了类似的矩阵求和问题解决方式[^5]。 --- ### 总结 尽管未直接检索到 Codeforces Round 1022 Div. 2 的具体内容,但以上提供了针对不同难度级别的典型解法及其扩展应用方向。希望这能帮助理解潜在的比赛考点。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值