2019HDU多校八 6665 Calabash and Landlord(离散化BFS)

本文介绍了一种通过离散化和广度优先搜索(BFS)算法来计算两个矩形在二维平面上形成的封闭区域数量的方法。利用特殊符号表示矩形边界,并将问题映射到15x15的网格上,通过BFS遍历未被矩形覆盖的区域,以此来计数独立的封闭区域。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

hdu6665

题意:

求两个矩形在二维平面内组成的封闭区域的个数

思路:

暴力讨论

赛中队友想暴力搞一下就被我否决了(情况太多有这时间还不如去开其他题?)

考虑对矩形离散化到一个 15 ∗ 15 15*15 1515的区域内,矩形的边界用特殊的符号表示,然后对这个区域进行 b f s bfs bfs就完事了。

#include<map>
#include<set>
#include<queue>
#include<stack>
#include<ctime>
#include<cmath>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e6 + 5;
const int INF = 0x3f3f3f3f;
const ull seed = 131;
const ll MOD = 1e9 + 7;
using namespace std;
struct Node{
    ll a, b;
    bool operator < (const Node x) const{
        return b > x.b;
    }
}p[maxn];
vector<int> xx, yy;
int vis[15][15];
struct cp{
    int x, y;
};
int to[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
void bfs(int x, int y, int id){
    queue<cp> q;
    while(!q.empty()) q.pop();
    vis[x][y] = id;
    cp a, b;
    a.x = x, a.y = y;
    q.push(a);
    while(!q.empty()){
        a = q.front();
        q.pop();
        for(int i = 0; i < 4; i++){
            b.x = a.x + to[i][0];
            b.y = a.y + to[i][1];
            if(b.x < 0 || b.y < 0 || b.x >= 15 || b.y >= 15) continue;
            if(vis[b.x][b.y] != 0) continue;
            vis[b.x][b.y] = id;
            q.push(b);
        }
    }
}
int main(){
    int T;
    scanf("%d", &T);
    while(T--){
       int x[5], y[5];
       xx.clear(), yy.clear();
       scanf("%d%d%d%d", &x[1], &y[1], &x[2], &y[2]);
       scanf("%d%d%d%d", &x[3], &y[3], &x[4], &y[4]);
       for(int i = 1; i <= 4; i++){
            xx.push_back(x[i]);
            yy.push_back(y[i]);
       }
       sort(xx.begin(), xx.end()), sort(yy.begin(), yy.end());
       xx.erase(unique(xx.begin(), xx.end()), xx.end());
       yy.erase(unique(yy.begin(), yy.end()), yy.end());
       for(int i = 1; i <= 4; i++){
            x[i] = lower_bound(xx.begin(), xx.end(), x[i]) - xx.begin() + 1;
            x[i] += (x[i] - 1);
       }
       for(int i = 1; i <= 4; i++){
            y[i] = lower_bound(yy.begin(), yy.end(), y[i]) - yy.begin() + 1;
            y[i] += (y[i] - 1);
       }

       memset(vis, 0, sizeof(vis));
       for(int i = x[1]; i <= x[2]; i++){
            vis[i][y[1]] = -1;
            vis[i][y[2]] = -1;
       }
       for(int i = x[3]; i <= x[4]; i++){
            vis[i][y[3]] = -1;
            vis[i][y[4]] = -1;
       }
       for(int i = y[1]; i <= y[2]; i++){
            vis[x[1]][i] = -1;
            vis[x[2]][i] = -1;
       }
       for(int i = y[3]; i <= y[4]; i++){
            vis[x[3]][i] = -1;
            vis[x[4]][i] = -1;
       }
       int ans = 0;
       for(int i = 0; i < 15; i++){
            for(int j = 0; j < 15; j++){
                if(vis[i][j] != -1 && vis[i][j] == 0){
                    ans++;
                    bfs(i, j, ans);
                }
            }
       }
       printf("%d\n", ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值