USACO--range

     就是因为这题是自己想出来的一种解题方法,所以才挂出来纪念一下,呵呵...我的解题思路和以前做的那个叫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);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值