坐标离散化技巧

题目:w*h的格子上画了n条垂直或水平的宽度为1的直线。求出这些线将格子划分成了多少个区域。

1<=w,h<=1000000.     1<=n<=500

思路:首先,一般会想到直接进行dfs或bfs,但w,h过大,无法直接搜索。坐标离散化的思想就是把有用的坐标提取出来,再建一个坐标系,把这些坐标按照顺序放在这个坐标系中。本题只需存储直线的x,y坐标和直线前后的。所以大小6n*6n就够了。


#include
#include
#include
#include
#include
#include
#include
#define ll __int64
#define INF 0x3fffffff
#define MAXN 105
using namespace std;

int w,h,n;
int dir[4][2]={{-1,0},{0,-1},{0,1},{1,0}};
int x1[MAXN],x2[MAXN],Y1[MAXN],y2[MAXN];
bool fld[MAXN*6][MAXN*6];//填充用
struct Point
{
    int x,y;
    Point(int x_=0,int y_=0):x(x_),y(y_){}
}point[MAXN*MAXN*6*6];

int compress(int *x1,int *x2,int w)
{
    vectorxs;
    for(int i=0;i=1&&tx1<=w) xs.push_back(tx1);
            if(tx2>=1&&tx2<=w) xs.push_back(tx2);
        }
    }
    sort(xs.begin(),xs.end());//有重复的,排序
    xs.erase(unique(xs.begin(),xs.end()),xs.end());
    for(int i=0;iq;
            Point p;
            p.x=x;p.y=y;
            q.push(p);
            while(!q.empty()){
                int sx=q.front().x;
                int sy=q.front().y;
                q.pop();
                for(int i=0;i<4;i++){
                    int xx=sx+dir[i][0];
                    int yy=sy+dir[i][1];
                    if(fld[xx][yy]||xx<0||xx>=w||yy<0||yy>=h) continue;
                    q.push(Point(xx,yy));
                    fld[xx][yy]=true;
                }
            }
        }
    }
    cout<>w>>h>>n;
    for(int i=0;i>x1[i];
    }
    for(int i=0;i>x2[i];
    }
    for(int i=0;i>Y1[i];
    }
    for(int i=0;i>y2[i];
    }
    solve();
    return 0;
}



你可能感兴趣的:(搜索)