Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

这样贪心可以吗?

Posted by martinblack954 at 2009-08-15 11:36:59 on Problem 2032 and last updated at 2009-08-15 11:39:38
#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:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator