1. 程式人生 > >洛谷P4417 [COCI2006-2007#2] STOL

洛谷P4417 [COCI2006-2007#2] STOL

題目描述

米爾科買了一套別墅,他想要邀請儘量多的人和他一起慶祝。他需要一張大的木質矩形桌子來讓他和他的嘉賓坐下。每張桌子可容納的人數等於它的周長(四邊長度的總和)。米爾科想要買一張即可在他的公寓裡放下,也可以坐下儘量多的人和他一起享用晚餐的桌子。桌子必須放置成四條邊都與公寓的牆平行的樣子。題目給出公寓內部的佈局,請問米爾科最多可以邀請多少人吃晚餐。

輸入輸出格式

輸入格式:

第一行包含兩個整數R和S(1<=R,S<=400),代表公寓的尺寸(R為寬,S為長),以下的R行中每一行都包含了S個準確的字元(沒有空格),代表這個正方形區域是沒有東西的('.') ,還是有東西的('X'),米爾科只等把桌子發在沒有東西的正方形區域裡。

輸出格式

輸出米爾科在放下他的桌子後能夠邀請來吃晚餐的人數

輸入輸出樣例

輸入樣例#1: 

2 2
..
..

輸出樣例#1:

7

輸入樣例#2:

4 4
X.XX
X..X
..X.
..XX

輸出樣例#2:

9

輸入樣例#3:

3 3
X.X
.X.
X.X

輸出樣例#3:

3

 

經過觀察得出,這題需要打O(n^2)-O(n^3)的題解,先考慮O(n^3)的解

首先列舉行和列

因為需要找出1-i行可以形成的矩形,所以我們另k從i搜尋到1

要成為矩形,每一行的連續空餘位置都必須一樣,所以sum[ i ] [ j ]表示第i行的第j列又多少個連續的空餘位置

如果要每一行的連續空餘位置一樣並且矩陣周長最大化,那麼矩陣的長度就是由目前找過最小的sum來決定

當搜尋到X時,就退出,每次找到矩陣都記錄一次最大值,故時間保證在O(n^3)以內

我講的不是很清晰,希望我清晰的程式碼能夠幫助您

程式碼:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<string>
using namespace std;
const int N=4e2+10;
int n,m;
int sum[N][N];
int maxx=0;
string s;
int read(){//弱智讀入 
	int t;cin>>t;
	return t;
}
int print(int x){//弱智輸出 
	cout<<x<<endl; 
}
int solve(int x,int y){//長和寬分別為x和y的矩陣的周長 
	return (x+y)<<1;
}
int main(){
	n=read();m=read();
	for(int i=1;i<=n;i++){
		cin>>s;
		for(int j=0;j<m;j++)
			if(s[j]=='.')sum[i][j+1]=sum[i][j]+1;//記錄字首和 
	}
	int minn;
	for(int i=1;i<=n;i++)//列舉 
		for(int j=1;j<=m;j++){
			minn=999999999;//記錄行的最小字首 
			for(int k=i;k>=1;k--){
				minn=min(minn,sum[k][j]);
				if(!minn)break;//當然不能為0 
				maxx=max(maxx,solve(i-k+1,minn));//記錄最大值 
			}
		}
	print(maxx-1);return 0;
}