HDU 2589 正方形划分(DFS+回溯)

来源:互联网 发布:我的世界pe村民交易js 编辑:程序博客网 时间:2024/06/06 19:37
Problem Description
一个边长为L的正方形可以分成 L*L个小正方形. 有N个石子放在 N个小正方形里,能否将它分成 N个 正方形,使得每个正方形里恰有一个石子且这N 个正方形恰好构成整个正方形 .
 

Input
输入数据首先包含一个整数T,表示测试实例的个数,然后是T组数据,每组第一行包含2个整数L,N,接下来有N行每行2个整数 r,c,表示第r行c列的小正方形里有一个石子 .1<L<=20;1<N<=L*L; 1<=r,c<=L.
 

Output
对于每个测试实例,如能将它分成 N个 正方形输出YES, 否则输出 NO
 

Sample Input
35 82 43 33 43 54 24 44 55 53 21 13 32 41 11 22 12 2
 

Sample Output
YESNOYES
 

//Must so#include<iostream>#include<algorithm>#include<string>#include<sstream>#include<cstring>#include<ctype.h>#include<queue>#include<vector>#include<set>#include<cstdio>#include<cmath>#define mem(a,x) memset(a,x,sizeof(a))#define inf 1<<29#define NN 1000006using namespace std;const double PI = acos(-1.0);typedef long long LL;bool vis[22][22];int mp[22][22];int L;int x,y;bool fd(){    for (int i = 1;i <= L;i++)    {        for (int j = 1;j <= L;j++)        {            if (vis[i][j] == 0)            {                x = i,y = j;                return 1;            }        }    }    return 0;}bool dfs(){    if (fd())    {        for (int r = 0;r <= L;r++)        {            int xx = x + r;            int yy = y + r;            if (xx > L||yy > L) break;            int cake = 0;            for (int i = x;i <= xx;i++)            {                for (int j = y;j <= yy;j++)                {                    if (mp[i][j] == 1) cake ++;                }            }            if (cake == 1)            {                for (int i = x;i <= xx;i++)                {                    for (int j = y;j <= yy;j++)                    {                        vis[i][j] = 1;                    }                }                int sx = x,sy = y;//这里注意,x,y定义在全局,递归过程中的改变需要手动修改回来!!!                if (dfs()) return 1;                //下面是回溯                x = sx,y = sy;                for (int i = x;i <= xx;i++)                {                    for (int j = y;j <= yy;j++)                    {                        vis[i][j] = 0;                    }                }            }        }        if (fd()) return 0;        return 1;    }    else return 1;}int main(){    int T;    cin>>T;    while (T--)    {        int n;        cin>>L>>n;        mem(mp,0);        mem(vis,0);        for (int i = 0,x,y;i < n;i++)        {            scanf("%d%d",&x,&y);            mp[x][y] = 1;        }        if (dfs()) puts("YES");        else puts("NO");    }    return 0;}

0 0
原创粉丝点击