HDU--3885[Find the Difference] 暴搜

25 篇文章 0 订阅
18 篇文章 0 订阅

题意:

就是QQ里的大家来找茬= =!。给两个n*m的整数矩形,求两个矩形间不同的小矩形,输出个数以及每个矩形的左上角、右下角的坐标。要求每个独立的小矩形满足至少有一个点不相同,他的周围一圈是相同的,且这个小矩形不能在其余这种矩形之内。

 

思路:

由于数据较小(N,M<=50)枚举每一个点,如果当前点是不同点,则从该点向外BFS,扩展出一个矩形。最后对所有矩形按要求排序,然后去掉一些被覆盖的矩形,输出即可。

 

PS.居然把qsort的比较函数写错了,查了一个晚上,唉,最近做题越来越不顺了 = =!

 

 

 CODE:

/*BFS*/
/*AC代码:46ms*/
#include <iostream>
#include <cstdio>
#include <memory.h>
#include <algorithm>
#include <queue>
#define MAXN 55
#define min(a,b) (a<b?a:b)
#define max(a,b) (a>b?a:b)
using namespace std;
struct Rect
{
    int x1,y1,x2,y2;
}rect[55*55];
struct Point
{
    int x,y;
    Point(int x1,int y1)
    {x=x1;y=y1;}
    Point(){}
};
int dir[8][2]={{-1,-1},{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1}};
int map1[MAXN][MAXN],map2[MAXN][MAXN];
bool vis[MAXN][MAXN];
bool flag[55*55];
int cnt;//矩形个数
int N,M,cas;
queue<Point>Q;

int cmp(const void *p1,const void *p2)
{
    if(((struct Rect *)p1)->x1!=((struct Rect *)p2)->x1)
        return ((struct Rect *)p1)->x1-((struct Rect *)p2)->x1;
    if(((struct Rect *)p1)->y1!=((struct Rect *)p2)->y1)
        return ((struct Rect *)p1)->y1-((struct Rect *)p2)->y1;


    if(((struct Rect *)p1)->x2!=((struct Rect *)p2)->x2)
        return ((struct Rect *)p2)->x2-((struct Rect *)p1)->x2;
    return ((struct Rect *)p2)->y2-((struct Rect *)p1)->y2;
}
void Init()
{
    int i,j;
    char s[300];
    for(i=1;i<=N;i++)
    {
        for(j=1;j<=M;j++)
            scanf("%d",&map1[i][j]);
    }
    for(i=1;i<=N;i++)
    {
        for(j=1;j<=M;j++)
            scanf("%d",&map2[i][j]);
    }
}
bool Judge(int x,int y)
{
    if(x>=1&&x<=N&&y>=1&&y<=M)
        return true;
    return false;
}
void Run(int dx,int dy,Rect &now)
{
    int i;
    Q.push(Point(dx,dy));
    if(dx<now.x1||dx>now.x2)
    {
        for(i=now.y1;i<=now.y2;i++)
            Q.push(Point(dx,i));
    }
    if(dy<now.y1||dy>now.y2)
    {
        for(i=now.x1;i<=now.x2;i++)
            Q.push(Point(i,dy));
    }
    now.x1=min(now.x1,dx);
    now.y1=min(now.y1,dy);
    now.x2=max(now.x2,dx);
    now.y2=max(now.y2,dy);
}
void BFS(int sx,int sy)
{
    int i,x,y;
    while(!Q.empty()) Q.pop();
    memset(vis,false,sizeof(vis));
    vis[sx][sy]=true;
    rect[cnt].x1=rect[cnt].x2=sx;
    rect[cnt].y1=rect[cnt].y2=sy;
    Q.push(Point(sx,sy));
    while(!Q.empty())
    {
        x=Q.front().x;
        y=Q.front().y;
        Q.pop();
        for(i=0;i<8;i++)
        {
            int dx=x+dir[i][0];
            int dy=y+dir[i][1];
            if(Judge(dx,dy)&&!vis[dx][dy])
            {
                vis[dx][dy]=true;
                if(map1[dx][dy]!=map2[dx][dy])
                {
                    Run(dx,dy,rect[cnt]);
                }
            }
        }
    }
    cnt++;
}
void Solve()
{
    int i,j;
    cnt=0;
    for(i=1;i<=N;i++)
    {
        for(j=1;j<=N;j++)
        {
            if(map1[i][j]!=map2[i][j])
            {
                BFS(i,j);
            }
        }
    }
    qsort(rect,cnt,sizeof(rect[0]),cmp);
    memset(flag,true,sizeof(flag));
    int num=0;
    for(i=0;i<cnt;i++)
    {
        if(!flag[i]) continue;
        for(j=i+1;j<cnt;j++)
        {
            if(!flag[j]) continue;
            if(rect[i].x1<=rect[j].x1&&rect[i].y1<=rect[j].y1&&rect[i].x2>=rect[j].x2&&rect[i].y2>=rect[j].y2)
            {
                flag[j]=false;
            }
        }
    }
    for(i=0;i<cnt;i++)
        num+=flag[i];
    printf("%d\n",num);
    for(i=0;i<cnt;i++)
    {
        if(flag[i])
            printf("%d %d %d %d\n",rect[i].x1,rect[i].y1,rect[i].x2,rect[i].y2);
    }
}
int main()
{
    while(scanf("%d%d",&N,&M)!=EOF)
    {
        Init();
        Solve();
    }
return 0;
}
/*
5 5
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0

0 0 0 0 1
0 0 1 0 0
0 1 0 1 0
0 0 1 0 0
1 0 0 0 0

1
1 1 5 5
*/


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

__简言

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值