码迷,mamicode.com
首页 > 其他好文 > 详细

HDU2589 正方形划分【DFS】

时间:2015-02-09 10:59:19      阅读:206      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=2589


题目大意:

有一个边长为L的正方形有L*L个小正方形,将N个小石子放在N个小正方形中,给你N个小石子所放

位置,那么问题来了:能否将这个变成为L的正方形分割成N个正方形,使得每个正方形中都含有1个

小石子,并且这N个正方形正好构成整个正方形。

测试样例1说明:

边长为5的大正方形里有8个小石子,正好能将大正方形分解成8个小正方形,且每个正方形中有1个

小石子。

技术分享


思路:

用DFS来做这道题。用Num[i][j]来表示从(1,1)到(i,j)的矩形中有多少个小石子(用来计算小正方形

中含有的小石子数),用vis[][]表示将包含1个小石子的正方形区域覆盖,用x,y来表示当前分解的正

方形的左上角坐标,k表示正方形的边长。每次找到没有覆盖的区域,记录坐标(x,y),开始遍历小

正方形的边长,直到找到刚好包含1个小石子的正方形区域,将其覆盖,然后接着深搜找到没有覆盖

的区域……如果没有找到刚好包含1个小石子的正方形区域,将其回溯到没有覆盖的状态继续深搜。

如果所有区域都能被覆盖,则说明满足条件,返回1。

注:设x1 = x + k,y1 = y + k。则计算从(x,y)到(x1,y1)的正方形中包含的小石子个数Count为:

Count = Num[x1][y1] - Num[x1][y-1] - Num[x-1][y1] + Num[x-1][y-1]。


AC代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;

int Map[22][22],Num[22][22],vis[22][22],L,N;

int DFS()
{
    int x,y,flag = 1;
    for(int i = 1; i <= L; ++i)     //找到未分割正方形的位置坐标
    {
        if(!flag)
            break;
        for(int j = 1; j <= L; ++j)
        {
            if(!vis[i][j])
            {
                x = i;
                y = j;
                flag = 0;
                break;
            }
        }
    }

    int k = 0;
    while(x+k <= L && y+k <= L)
    {
        int x1 = x + k;
        int y1 = y + k;
        int Count = Num[x1][y1] - Num[x1][y-1] - Num[x-1][y1] + Num[x-1][y-1];//计算当前正方形内点的数目
        if(Count > 1)   //大于1不符合
            break;
        else if(Count == 1) //当前正方形中正好有1个点
        {
            for(int i = x; i <= x1; ++i)        //填充该正方形
                for(int j = y; j <= y1; ++j)
                    vis[i][j] = 1;
            if(DFS())                           //继续填充,满足所求条件返回1.
                return 1;
            for(int i = x; i <= x1; ++i)        //回溯到未填充该正方形的状态
                for(int j = y; j <= y1; ++j)
                    vis[i][j] = 0;
        }

        k++;
    }

    for(int i = 1; i <= L; ++i)         //判断是否满足所求条件
        for(int j = 1; j <= L; ++j)
            if(!vis[i][j])
                return 0;
    return 1;
}

int main()
{
    int T;
    cin >> T;
    while(T--)
    {
        cin >> L >> N;
        memset(Num,0,sizeof(Num));
        memset(vis,0,sizeof(vis));
        memset(Map,0,sizeof(Map));

        for(int i = 0; i < N; ++i)
        {
            int x,y;
            cin >> x >> y;
            Map[x][y] = 1;
        }
        for(int i = 1; i <= L; ++i)
            for(int j = 1; j <= L; ++j)
                Num[i][j] = Num[i-1][j] + Num[i][j-1] - Num[i-1][j-1] + Map[i][j];

        if(DFS())
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }

    return 0;
}



HDU2589 正方形划分【DFS】

标签:

原文地址:http://blog.csdn.net/lianai911/article/details/43667249

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!