就是因为这题是自己想出来的一种解题方法,所以才挂出来纪念一下,呵呵...我的解题思路和以前做的那个叫To the max 的动态规划的题目有点像。虽然我这个算法的时间复杂度吓人的O(n^3),嘿嘿...
/*
ID: morgan_xww
LANG: C
TASK: range
*/
/**
我算法的时间复杂度是O(n^3)
题目中说(2<=n<=250),但是实际测试数据最大的n=75,
所以我的程序最大运行时间为0.054s.
我的算法是:
不好用语言描述,还是举例说明吧,比如这组数据:
5
10111
00111
11111
00111
10110
一个大循环r=1...(n-1),r表示起始行,
就说r=1的情况,一个数组a[]=map[1][].
即a[]={10111},把第2行与a[]求&运算,
得a[]={00111},调用函数fun(),求出a中长度为2的连续的1的串的个数,
找到有2个,即找到边长为2的正方形2个;接着把第3行与a[]求&,再调用
fun(),找边长为3的正方形的个数;接着把第4行与a[]求&,.......
上面都是r=1,都是以第1行为起始行找到的各个边长的正方形的个数,
r=2时,就是第2行为起始行,.....循环到r=n-1.即找到所有的各边长的
正方形的个数。
**/
#include <stdio.h>
int n, ans[251];
char map[251][251];
/* 函数fun(a[], len)是要找出a[]中长度为len的连续的1的串的数量 */
int fun(char a[], int len)
{
int i, s=0, tag=0;
for (i=0; i<n; i++)
{
if (a[i])
{
s++;
if (s >= len)
{
ans[len]++;
tag = 1;
}
}
else
s = 0;
}
if (tag) return 1;
else return 0;
}
int main()
{
//freopen("range.in", "r", stdin);
//freopen("range.out", "w", stdout);
int r, i, j;
char c, a[251];
scanf("%d", &n);
for (i=0; i<n; i++)
{
getchar();
for (j=0; j<n; j++)
{
c = getchar();
map[i][j] = c-'0';
}
}
for (r=0; r<n-1; r++)
{
for (j=0; j<n; j++)
a[j] = map[r][j];
for (i=r+1; i<n; i++)
{
for (j=0; j<n; j++)
a[j] &= map[i][j];
if (!fun(a, i-r+1))
break;
}
}
for (i=2; i<=n; i++)
if (ans[i])
printf("%d %d/n", i, ans[i]);
exit(0);
}