hdu2589(dfs)

来源:互联网 发布:godaddy域名dns修改 编辑:程序博客网 时间:2024/06/03 23:48

正方形划分

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 479    Accepted Submission(s): 262


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


题意:给定边长为l的正方形,在里面放n个点,求能不能把这个正方形变成n个小正方形,并且每个正方形包含1个刚才的点。

思路:用dfs来做。很经典

#include<iostream>#include<stdio.h>  #include<string.h>  #include<math.h>#include<algorithm>using namespace std;  int map[25][25];int num[25][25];      //num[i][j]来记录(1,1)到(i,j)中包含的点de个数 bool vis[25][25];       //表示有没有被覆盖 int l,n;bool dfs(){bool flag=false;int x,y;for(int i=1;i<=l;i++)      //找到第一个没有被覆盖的坐标,以此为这个正方形的左上角 {if(flag==true)break;for(int j=1;j<=l;j++){if(!vis[i][j]){x=i;y=j;flag=true;break;}}}if(flag==false)return true;    //直到所有的坐标都被覆盖则返回true int k=0;                         //k为边长减1 while(x+k<=l&&y+k<=l)            //寻找合适边长的正方形 {int x1=x+k;int y1=y+k;int cnt=num[x1][y1]-num[x1][y-1]-num[x-1][y1]+num[x-1][y-1];    //利用num数组算出这个小正方形中的点数 if(cnt>1)break;else if(cnt==1)             //点为1的时候 {bool can=true;for(int i=x;i<=x1;i++){for(int j=y;j<=y1;j++){if(vis[i][j]==true){can=false;break;}}}if(can==true)           //而且里面所有坐标都没被别的小正方形覆盖,就用当前小正方形覆盖,接着深搜 {for(int i=x;i<=x1;i++)for(int j=y;j<=y1;j++)vis[i][j]=true;if(dfs())return true;for(int i=x;i<=x1;i++)for(int j=y;j<=y1;j++)vis[i][j]=false;}}k++;}return false;     //对于有没有覆盖的坐标而坐标形成正方形里无法覆盖点的情况返回false }int main(){int t;cin>>t;while(t--){memset(map,0,sizeof(map));memset(num,0,sizeof(num));memset(vis,false,sizeof(vis));cin>>l>>n;int x,y;for(int i=0;i<n;i++){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;}}



原创粉丝点击