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

D - 小晴天老师系列——晴天的后花园

时间:2015-04-25 06:48:39      阅读:211      评论:0      收藏:0      [点我收藏+]

标签:

D - 小晴天老师系列——晴天的后花园

Time Limit: 10000/5000MS (Java/Others)    Memory Limit: 128000/64000KB (Java/Others)
Submit Status

Problem Description

小晴天非常漂亮的后花园,打算以后退休之后在里面种种花,养养草,所以现在小晴天打算为他的后花园围上栅栏。

小晴天的后花园可以看成是一个m*n的矩形,但是其中有一些地方种了树,这些地方都不能安装栅栏,现在小晴天把后花园的平面图告诉你了,请你帮忙设计一个最大的矩形栅栏。

Input

单组数据,第一行包括两个整数m,n(1<=m,n<=500),接下来m行,每行包括n个字符,仅由‘x‘和‘.‘组成(ASCII码分别是120与46).

其中‘x’表示这个方格有树木,‘.’表示这个点可以建造栅栏

Output

若可以围成一个闭合栅栏,输出一个整数,表示栅栏能打到的最大周长

否则输出impossible

Sample Input

4 5
.....
.x.x.
.....
.....
2 2
.x
x.
2 5
.....
xxxx.

Sample Output

14
impossible
impossible

Hint

样例一可以绕着整个图一圈,周长为2*(4+3)=14

样例二与三因为有树木的存在,不能建造一个闭合的栅栏。

本题为单文件读写,样例包括三个文件

题意:

  输入m,n,表示有一个大小为m*n的地图,然后输入那地图,‘.‘表示空地,可以建栏杆,‘x‘表示树木,不能够在建栏杆,问你该地图所能够围成的最大矩形栏杆需要多少个栏杆,(所围成的矩形不包括树木,只能由栏杆组成),在做这一题主要是寻找最大的矩形,没有规律怎么办,那就暴搜吧,从每一个点作为起始点(矩形的左上端点),不过搜也要搜得有水平。

  首先,找出该起始点(x,y)的右边最大能够到达的点,最大长度设为i,然后再从(x,y+i)向下找,所能够到达的点,最大长度设为j,然后再从(x+j,y+i)~(x+j,y)去判断是否都为‘.‘空地,如果是的话,再从(x+j,y)~(x,y)去判断是否为‘.‘空地,如果是的话说明能够构成一个矩形。

  记录该矩形的最大长度i和j,栏杆的最大数目sum=max((i+j)*2,sum);

  最后在判断sum是否为0,为0输出 impossible,否则输出sum;

(PS:在每次获取i和j的时候可以判断(i+m-1)*2或者(i+j)*2是否大于sum,如果比sum还小的话,就没有必要再进行接下去的判断。)

技术分享
#include <iostream>
#include <stdio.h>
#include <string.h>
#define Max(a,b)a>b?a:b
using namespace std;
char Map[1010][1010];
int Len_X,Len_Y;    /*地图的最大长度和最大宽度*/
int sum;        /*记录栏杆的最大数量*/
int Ret_Y(int x,int y)/*获取(x,y)的右边的最大长度*/
{
    int j;
    for(j=1;j+y<=Len_Y;j++)
    {if(Map[x][j+y]==x)break;}
    return j-1;
}

int Ret_X(int x,int y)/*获取(x,y)的向下的最大长度*/
{
    int j;
    for(j=1;j+x<=Len_X;j++)
    {if(Map[x+j][y]==x)break;}
    return j-1;
}

void Work(int x,int y)
{
    int i,j,k,l,ii,jj,kk,ll,sign1,sign2;
   // printf("%d %d:\n",x,y);
    for(i=Ret_Y(x,y);i>=1;i--)  /*获取(x,y)最大右边距离,然后长度递减查找*/
    {
        if(Map[x][y+i]==.&&(i+Len_X-1)*2>sum)/*判断为空地和剪枝*/
        {
            for(j=Ret_X(x,y+i);j>=1;j--)    /*获取(x,y+i)最大向下距离,然后长度递减查找*/
            {
                if(Map[x+j][y+i]==.&&(i+j)*2>=sum)/*判断为空地和剪枝*/
                {
                     for(k=1,sign1=0;k<=i;k++)  /*判断矩形下边是否都为空地*/
                     {
                         if(Map[j+x][y+i-k]==.)sign1++;
                         else break;
                     }
                     if(sign1==i)/*矩形下边符合条件*/
                     {
                        for(k=1,sign2=0;k<j;k++)   /*判断矩形左边是否都为空地*/
                        {
                            if(Map[j+x-k][y]==.)sign2++;
                            else break;
                        }
                        if(sign2==j-1)/*符合构成矩形条件*/
                        {
                            //printf("\t%d %d\n",i,j);
                            sum=Max(sum,(i+j)*2);/*获取最大值,其实每一次获取的都是最大值*/
                           // return;
                        }
                     }
                }
            }
        }
        else break;
    }
    return ;
}

int main()
{
    int i,j;
    while(scanf("%d%d",&Len_X,&Len_Y)!=EOF)
    {
        memset(Map,x,sizeof(Map));/*设置围墙*/
        for(i=1;i<=Len_X;i++)
        {
            scanf(" %s",Map[i]+1);
            Map[i][Len_Y+1]=x;/*设置围墙*/
        }
        for(i=1,sum=0;i<=Len_X;i++)
        {
            for(j=1;j<=Len_Y;j++)
            {
                if(Map[i][j]==.)
                {
                    Work(i,j);  /*搜索每一个点*/
                }
            }
        }
        if(sum)printf("%d\n",sum);
        else printf("impossible\n");
    }
    return 0;
}
/*
4 4
....
....
..x.
.x.x

*/
View Code

 

D - 小晴天老师系列——晴天的后花园

标签:

原文地址:http://www.cnblogs.com/LWF5201314614/p/4455159.html

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