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

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

*/

时间: 2024-12-15 13:13:56

D - 小晴天老师系列——晴天的后花园的相关文章

acdream 小晴天老师系列——晴天的后花园 (暴力+剪枝)

小晴天老师系列——晴天的后花园 Time Limit: 10000/5000MS (Java/Others)    Memory Limit: 128000/64000KB (Java/Others) Problem Description 小晴天非常漂亮的后花园,打算以后退休之后在里面种种花,养养草,所以现在小晴天打算为他的后花园围上栅栏. 小晴天的后花园可以看成是一个m*n的矩形,但是其中有一些地方种了树,这些地方都不能安装栅栏,现在小晴天把后花园的平面图告诉你了,请你帮忙设计一个最大的矩形

F - 小晴天老师系列——苹果大丰收

F - 小晴天老师系列——苹果大丰收 Time Limit: 2000/1000MS (Java/Others)    Memory Limit: 128000/64000KB (Java/Others) Submit Status Problem Description 小晴天的后花园有好多好多的苹果树,某天,苹果大丰收~小晴天总共摘了M个苹果,我们假设苹果之间是不可分辨的. 为了保存苹果,小晴天买了N个一模一样的箱子,想要把苹果放进去,允许有的箱子是空的,请问小晴天有多少种不同的放法呢? 例

acdream 小晴天老师系列——苹果大丰收(DP)

小晴天老师系列——苹果大丰收 Problem Description 小晴天的后花园有好多好多的苹果树,某天,苹果大丰收~小晴天总共摘了M个苹果,我们假设苹果之间是不可分辨的. 为了保存苹果,小晴天买了N个一模一样的箱子,想要把苹果放进去,允许有的箱子是空的,请问小晴天有多少种不同的放法呢? 例如对于4个苹果,3个箱子,2+1+1和1+2+1和1+1+2 是同一种分法. Input 多组数据,首先是一个正整数t(t<=100)表示数据的组数. 每组数据均包含二个整数M和N(1<=M,N<

G - 小晴天老师系列——可恶的墨水瓶

G - 小晴天老师系列——可恶的墨水瓶 Time Limit: 2000/1000MS (Java/Others)    Memory Limit: 128000/64000KB (Java/Others) Submit Status Problem Description 小晴天老师正在备课,这时,可恶的墨水瓶突然自己打翻了!悲剧发生了!小晴天的备课稿都被墨水弄脏了.... 不过小晴天很乐观~这时他把他的一张纸分成n*m个格子,其中有一些格子被墨水涂黑了,有的没有.那么小晴天想知道,最大的一块

E - 小晴天老师系列——我有一个数列!

E - 小晴天老师系列——我有一个数列! Time Limit: 20000/10000MS (Java/Others)    Memory Limit: 128000/64000KB (Java/Others) Submit Status Problem Description 小晴天:“我有一个数列!” 小晴天:“我还要有很多很多的数列!” 于是小晴天就把这个数列的所有连续子数列写出来. 然后小晴天把每个连续子数列中的最大的数写出来. 那么,有多少个比K大呢? Input 多组数据,首先是一

[ACDream]小晴天老师系列——竖式乘法

直接上题目: 小晴天老师系列——竖式乘法 Time Limit: 4000/2000MS (Java/Others)    Memory Limit: 128000/64000KB (Java/Others) Submit Status Problem Description 小晴天是ACdream团队中最牛的老师之一,他最擅长数学运算~这天他翻开一本<AC is not a dream>杂志,发现最后一页有一道很经典的思维题,题目很简单,每个框填写一个数字,构成一个竖式,每个数的最高位不能为

【acdream】小晴天老师系列——竖式乘法

C - 小晴天老师系列——竖式乘法 Time Limit: 4000/2000MS (Java/Others)    Memory Limit: 128000/64000KB (Java/Others) Submit Status Problem Description 小晴天是ACdream团队中最牛的老师之一,他最擅长数学运算~这天他翻开一本<AC is not a dream>杂志,发现最后一页有一道很经典的思维题,题目很简单,每个框填写一个数字,构成一个竖式,每个数的最高位不能为0,但

acdream 小晴天老师系列——竖式乘法(简单穷举)

小晴天老师系列——竖式乘法 Time Limit: 4000/2000MS (Java/Others)    Memory Limit: 128000/64000KB (Java/Others) Problem Description 小晴天是ACdream团队中最牛的老师之一,他最擅长数学运算~这天他翻开一本<AC is not a dream>杂志,发现最后一页有一道很经典的思维题,题目很简单,每个框填写一个数字,构成一个竖式,每个数的最高位不能为0,但是有一些数字被隐藏掉了,然后让你根据

小布老师全部视频

http://www.boobooke.com/bbs/thread-7630-1-1.html 小布老师全部视频(更新时间:2011-08-10更新内容:Oracle 11g PL/SQL 23-27讲) 时间, 老师, Fundamentals, 视频 本帖最后由 river7000 于 2012-1-31 09:16 编辑 播布客Oracle交流群"197276682"群(上限500人)已满员,209931123群刚建立,须要增加的群友请加,我会缴请小布老师增加新建的群,欢迎小布