dp题。用dp[i][j][m]表示左上角为(i,j),边长为m的正方形是否完整。那么
如果dp[i][j][m]完整,则当且仅当dp[i][j][m-1],dp[i+1][j][m-1],dp[i][j+1][m-1],dp[i+1][j+1][m-1]的正方形也是完整的(画个图就很清晰了)。由于我们从上到下,从左到右扫描每个点,在每一轮i,j用过一次,就不会再使用,所以只需用二维数组保存dp[i][j],即可。
时间复杂度为O(n^3),空间复杂度为O(n^2)。analysis中有个时间复杂度为O(n^2),空间O(n)的解法。
#include <iostream>
#include <fstream>
using namespace std;
ifstream fin("range.in");
ofstream fout("range.out");
#ifdef _DEBUG
#define out cout
#define in cin
#else
#define out fout
#define in fin
#endif
bool dp[250][250];
int side_len;
void input()
{
in>>side_len;
char t;
for(int i=0;i<side_len;++i){
for(int j=0;j<side_len;++j){
while( in.get(t)&&isspace(t) );
dp[i][j] = t-'0';
}
}
}
void solve()
{
input();
for(int w = 2;w<=side_len;++w){
int cnt = 0;
for(int i=0;i<side_len;++i){
for(int j=0;j<side_len;++j){
if(i+w<=side_len&&j+w<=side_len){
dp[i][j] = dp[i][j]&&dp[i+1][j]&&dp[i][j+1]&&dp[i+1][j+1];
if(dp[i][j])
cnt++;
}
}
}
if(cnt!=0){
out<<w<<" "<<cnt<<endl;
}
}
}
int main(int argc,char *argv[])
{
solve();
return 0;
}