| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
这样贪心可以吗?#include "stdio.h"
#define M 13
int a[M][M],w,h,ma1[M][M],tot;
int ch[M][M];
bool b[M][M];
void dfs(int x,int y)//这里是搜索,找出以每个点为左上角,能放的最大正方形边长
{//后面的操作均以这个边长为准
int i,j;
if(a[x][y]==0) return;
ma1[x][y]=1;
while(x+ma1[x][y]<h&&y+ma1[x][y]<w)
{
for(i=x;i<=x+ma1[x][y];i++)
{
if(a[i][y+ma1[x][y]]==0)
break;
}
if(i<=x+ma1[x][y]) break;
for(i=y;i<=y+ma1[x][y];i++)
if(a[x+ma1[x][y]][i]==0) break;
if(i<=y+ma1[x][y]) break;
ma1[x][y]++;
}
}
void se(int x,int y)//以a[x][y]为左上角放入正方形
{
int i,j,k;
for(i=x;i<x+ma1[x][y];i++)//检验区域内有没有未被覆盖的点
{
for(j=y;j<y+ma1[x][y];j++)
if(ch[i][j]==0)//ch表示该点被覆盖了几次,由于有ma1的限制,所以不会找到坏点
break;
if(j<y+ma1[x][y]) break;
}
if(i<x+ma1[x][y])//说明有未被覆盖的点,放入正方形
{
tot++;
b[x][y]=1;//表示该点放入了正方形
for(i=x;i<x+ma1[x][y];i++)
{
for(j=y;j<y+ma1[x][y];j++)
ch[i][j]++;//区域覆盖,ch+1
}
}
}
void de(int x,int y)//以a[x][y]为左上角删除正方形
{
int i,j,k;
for(i=x;i<x+ma1[x][y];i++)//检验区域内的点是否都被覆盖了两次或以上
{
for(j=y;j<y+ma1[x][y];j++)
if(ch[i][j]==1)//添加操作中已经保证每个点都被覆盖
break;
if(j<y+ma1[x][y]) break;
}
if(i==x+ma1[x][y])//是则删除
{
tot--;
b[x][y]=0;
for(i=x;i<x+ma1[x][y];i++)
{
for(j=y;j<y+ma1[x][y];j++)
ch[i][j]--;
}
}
}
int main()
{
int i,j,l;
//freopen("in2.txt","r",stdin);
while(scanf("%d%d",&w,&h)>0)
{
//w=size;h=size;
if(w==0&&h==0) break;
if(w==0||h==0) continue;
for(i=0;i<h;i++)
for(j=0;j<w;j++)
{
scanf("%d",&a[i][j]);
ma1[i][j]=0;
ch[i][j]=0;b[i][j]=0;
}
for(i=0;i<h;i++)
for(j=0;j<w;j++)
{
dfs(i,j);
}
/*for(i=0;i<h;i++)
{
for(j=0;j<w;j++)
printf("%d ",ma1[i][j]);
printf("\n");
}printf("\n");*/
tot=0;
if(w>h) l=h;
else l=w;
for(;l>0;l--)//贪心放入正方形,先放大的,再放小的
for(i=0;i<h;i++)
{
for(j=0;j<w;j++)
{
if(ma1[i][j]==l)
se(i,j);
}
}
for(l=2;l<=h&&l<=w;l++)//删除某些重复区域的正方形,先小再大
/*if(w>h) l=h;
else l=w;
for(;l>1;l--)*/
for(i=0;i<h;i++)
for(j=0;j<w;j++)
if(b[i][j])
if(ma1[i][j]==l)
de(i,j);
printf("%d\n",tot);
}
return 0;
}
PS:我用随机生成的01矩阵和网上搜到的代码对比,半个小时内随机生成的所有01的10维方阵,这段代码的网上的AC代码答案都一样,不知哪里错……
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator