[UVALive 6663 Count the Regions] (dfs + 离散化)

链接:https://icpcarchive.ecs.baylor.edu/index.php?

option=com_onlinejudge&Itemid=8&page=show_problem&problem=4675

题目大意:

在一个平面上有 n (1<=n<=50) 个矩形。给你左上角和右下角的坐标(0<=x<=10^6, 0<=y<=10^6)。问这些矩形将该平面划分为多少块。

解题思路:

因为n非常小,能够对整个图进行压缩。仅仅要不改变每条边的相对位置。对答案没有影响。

能够将这些矩形的坐标离散化,然后把边上的点标记一下。之后进行简单dfs就可以。(注意离散化的时候,两条边之间至少要隔一个距离)

代码:

/*
ID: [email protected]
PROG:
LANG: C++
*/
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<string>
#include<fstream>
#include<cstring>
#include<ctype.h>
#include<iostream>
#include<algorithm>
#define INF (1<<30)
#define PI acos(-1.0)
#define mem(a, b) memset(a, b, sizeof(a))
#define For(i, n) for (int i = 0; i < n; i++)
using namespace std;
const int MOD = 1000000007;
typedef long long ll;
using namespace std;
struct node {
    int a, b, c, d;
} rec[600];
int x[1200], y[1200];
int xp[1000100], yp[1000100];
int mp[240][240], n;
int lx, ly;
void gao() {
    for (int i = 0; i < n; i++) {
        int A = xp[rec[i].a];
        int B = yp[rec[i].b];
        int C = xp[rec[i].c];
        int D = yp[rec[i].d];
        for (int j = A; j <= C; j++) mp[j][D] = mp[j][B] = 1;
        for (int j = D; j <= B; j++) mp[A][j] = mp[C][j] = 1;
    }
}
int dir[4][2] = {{0, -1}, {0, 1}, {1, 0}, { -1, 0}};
bool in(int x, int y) {
    return (x >= 0 && y >= 0 && x < 2 * lx + 1 && y < 2 * ly + 1);
}
void dfs(int x, int y) {
    mp[x][y] = 1;
    for (int i = 0; i < 4; i++) {
        int xx = x + dir[i][0];
        int yy = y + dir[i][1];
        if (in(xx, yy) && !mp[xx][yy]) {
            dfs(xx, yy);
        }
    }
}
int main() {
    while(scanf("%d", &n) != EOF && n) {
        for (int i = 0; i < n; i++) {
            scanf("%d%d%d%d", &rec[i].a, &rec[i].b, &rec[i].c, &rec[i].d);
            x[2 * i] = rec[i].a;
            x[2 * i + 1] = rec[i].c;
            y[2 * i] = rec[i].b;
            y[2 * i + 1] = rec[i].d;
        }
        sort(x, x + 2 * n);
        sort(y, y + 2 * n);
        lx = unique(x, x + 2 * n) - x;
        ly = unique(y, y + 2 * n) - y;
        for (int i = 0; i < lx; i++) {
            xp[x[i]] = 2 * i + 1;
        }
        for (int j = 0; j < ly; j++) {
            yp[y[j]] = 2 * j + 1;
        }
        memset(mp, 0, sizeof(mp));
        gao();
        int fk = 0;
        for (int i = 0; i < 2 * lx; i++) {
            for (int j = 0; j < 2 * ly; j++) if (mp[i][j] == 0) {
                    dfs(i, j);
                    fk++;
                }
        }
        cout << fk << endl;
    }
    return 0;
}
时间: 2024-10-31 13:36:58

[UVALive 6663 Count the Regions] (dfs + 离散化)的相关文章

UVALive 6663 Count the Regions --离散化+DFS染色

题意:给你n(n<=50)个矩形(左上角坐标和右下角坐标),问这些矩形总共将平面分成多少个部分.坐标值可能有1e9. 分析:看到n和坐标的范围,容易想到离散化,当时就没想到离散化以后怎么判断区域个数.后来看别人代码才知道,可以将边界上的点vis赋为1,那么枚举所有哈希后的平面上的点,遇到一个vis=0的点就从这点一直搜过去,搜到边界自动会停止了,因为边界vis=1,并且ans++,就可以了.真是太弱.. 代码: #include <iostream> #include <cstdi

UVALive 6663 Count the Regions 离散+bfs染色_(:зゝ∠)_

题目链接:点击打开链接 gg..== #include <cstdio> #include <cstring> #include<iostream> #include <queue> #include <set> #include <map> #include <algorithm> #include <string> using namespace std; #define ll long long #def

UVALive 6663 Count the Regions (离散化,染色,dfs)

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4675 题意: 二维平面内给出若干矩形,平面被矩形的边分为若干个区域,求一共有多少区域. 分析: 由于矩形只有50个,离散化后的平面大约是100*100的.不妨对于每个矩形覆盖的区域进行染色(用二进制位状压),相同颜色的联通块就是一个区域,只要dfs找联通块的个数即可.值得注意

UvaLive 6663 Count the Regions 离散化+DFS

链接:http://vjudge.net/problem/viewProblem.action?id=49408 题意:在平面内给出若干个矩形,求出它们能将整个平面分成多少份. 思路:刚开始一眼看到觉得是几何题,但是发现最多只有50个矩形后,灵光一闪觉得直接离散化再暴力就可以了.把所有矩形的x,y坐标分别离散化,并且为了防止出现离散的太近导致矩形之前没有空隙的情况,将所有点离散化的坐标记作偶数坐标.然后DFS找到所有矩形之间的空隙. 代码: #include<iostream> #includ

UVALIve6663--Count the Regions【离散化+搜索】

题意:一个平面上给你最多50个矩形,可以相交.覆盖,问他们把平面分割成了几部分,整个图形外面广大的空白区域也算一部分. 记得以前见过这种题,当时不会做也没做.现在看到这题还是没想法.在吴琦的讲解和代码下终于弄明白了. 思路是这样,根据他给的坐标点,排序.去重,然后重新构建一个图,至少在相邻两个点之间空出一个点表示被分割的区域,这样之后才能进行搜索,这实际上是把整个图形压缩下来,将中间的空白区域缩小,然后再根据原来的边的信息在新的图里标记出边的信息.然后进行搜索 #include<cstring>

DFS染色解决区域分块问题UVALive 6663

怪我比赛的时候想法太过于杂乱了. 注重于区域的属性了.甚至还想用状态压缩或者是hash来描述分块的区域. 其实我们的可以宏观的角度去审视这个问题.就是求分区的问题.那么我们完全可以标记边框的值为1.即不可行走. 那么我们扫描整片区域.统计一个区域 .就用DFS把这整片区域给覆盖.然后继续扫描下去. 离散化在这里使用. 注意点:在于这是一个数区间块数的问题.假如2者数据没有相差一.也会把一块区域给覆盖掉.这是一个考虑会不会影响离散化后的相邻问题的一个问题. 比赛的时候我当时也没注意.也许以后离散化

HDU 5877 Weak Pair(树状数组+dfs+离散化)

http://acm.hdu.edu.cn/showproblem.php?pid=5877 题意: 给出一棵树,每个顶点都有权值,现在要你找出满足要求的点对(u,v)数,u是v的祖先并且a[u]*a[v]<=k. 思路: 转化一下,a[v]<=k/a[u],k/a[u]的最大值也就是k/a[v],也就是寻找<=k/a[v]的个数,到这儿,是不是很像树状数组? 我们只需要从根开始dfs,插入到树状数组中,并且查询即可.注意这道题目需要离散化一下. 1 #include <iostr

Leetcode 130 Surrounded Regions DFS

将内部的O点变成X input X X X XX O O X X X O XX O X X output X X X XX X X XX X X XX O X X DFS图所有边上的点,将边上的O以及其联通域变为T,然后将内部的O变为X,外部的T变为O,本质是种子填充算法. 此题对于is_in这个函数要注意, 不要用(x < m) && (x >= 0) && (y < n) && (y >= 0) 会堆栈溢出!!原因是会出现边上的点

UVALive 6884 GREAT + SWERC = PORTO dfs模拟

题目连接: https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4896 We want to have a great SWERC at Porto this year and we approached this challenge in several ways.We even framed it as a word add