求白方块的个数,这个用的是N^3的算法,之后我在woj1012中会更新N^2 的算法
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1067
/*
题目:经典DP
分析:状态方程 f(i,j),为以 i,j为右下角的 rect的个数,然后求和即可。
预处理,计算每行到位置 j的 rect的个数,然后从下向上计算,
保存长度最小的 rect个数即可(大的会被截取)。
说明:先计算一维,在利用一维求解二维,其实都是在求解一维。
本题可以利用单调队列,做简单的优化,但是基于概率的。
记录到每个位置上面的最近的小于当前长度节点,然后跳着查找。
如果存在相邻的非递增序即可优化,不过系数有点大,与数据状态有关。
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
char maps[ 105 ][ 105 ];
int line[ 105 ][ 105 ];
int rect[ 105 ][ 105 ];
int main()
{
freopen("in.cpp", "r", stdin);
//freopen("out.cpp", "w", stdout);
int n;
while(scanf("%d",&n) != EOF)
{
int i,j,k,ans=0;
for(i=1;i<=n;i++) scanf("%s",&maps[i][1]);//scanf可以这样读取输入,长见识了
memset( line, 0, sizeof( line ) );
memset( rect, 0, sizeof( rect ) );
//第i行包含j位置的连续白方块个数
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(maps[i][j]=='.') line[i][j]=line[i][j-1]+1;
//包含i,j位置的白方块个数
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
int minl=line[i][j];
for(k=i;k>0;k++)
{
if(minl==0) break;
if(minl>line[k][j]) minl=line[k][j];
rect[k][j] +=minl;
}
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++) ans +=rect[i][j];
printf("%d\n",ans);
}
return 0;
}
使用cin,cout输入输出也行
/*
题目:经典DP
分析:状态方程 f(i,j),为以 i,j为右下角的 rect的个数,然后求和即可。
预处理,计算每行到位置 j的 rect的个数,然后从下向上计算,
保存长度最小的 rect个数即可(大的会被截取)。
说明:先计算一维,在利用一维求解二维,其实都是在求解一维。
本题可以利用单调队列,做简单的优化,但是基于概率的。
记录到每个位置上面的最近的小于当前长度节点,然后跳着查找。
如果存在相邻的非递增序即可优化,不过系数有点大,与数据状态有关。
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
char maps[ 105 ][ 105 ];
int line[ 105 ][ 105 ];
int rect[ 105 ][ 105 ];
int main()
{
//freopen("in.cpp", "r", stdin);
//freopen("out.cpp", "w", stdout);
int n;
while(cin>>n)
{
//cout<<n<<endl;
int i,j,k,ans=0;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++) cin>>maps[i][j];
/*
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++) cout<<maps[i][j];
cout<<endl;
}
*/
memset( line, 0, sizeof( line ) );
memset( rect, 0, sizeof( rect ) );
//第i行包含j位置的连续白方块个数
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(maps[i][j]=='.') line[i][j]=line[i][j-1]+1;
//包含i,j位置的白方块个数
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
int minl=line[i][j];
for(k=i;k>0;k++)
{
if(minl==0) break;
if(minl>line[k][j]) minl=line[k][j];
rect[k][j] +=minl;
}
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++) ans +=rect[i][j];
cout<<ans<<endl;
}
return 0;
}