Home on the Range

来源:互联网 发布:淘宝lol封号原理 编辑:程序博客网 时间:2024/05/18 00:07

题意:有一个N×N的矩阵,矩阵元素为0或者1。统计矩阵中边长>=2并且全部由1组成的方阵的数量。

解题思路

  1. DP问题。设f[i][j] = k,表示以(i, j)为左上角的方阵最大边长为k
  2. 滚雪球过程:当matrix[i][j] == 0的时候,f[i][j] = 0。否则f[i][j] = min (f[i + 1][j], f[i][j + 1], f[i][j]),其中越界的坐标f值为0
  3. DP完成后,用count[i]统计边长为i的方阵个数,初始化为0。遍历一遍f[i][j],若f[i][j] = k,则将count[2..k]++
  4. 遍历完成后根据count里面的内容输出即可

代码

/*ID: zc.rene1LANG: CPROG: range*/#include<stdio.h>#include<stdlib.h>#include<string.h>#define MAX_N 250int GetMin(int a, int b, int c){    int min = a;    if (b < min)    {min = b;    }    if (c < min)    {min = c;    }        return min;}int main(void){    FILE *fin, *fout;    int N, i, j, min;    char c;    int matrix[MAX_N][MAX_N];    int f[MAX_N + 1][MAX_N + 1];    int count[MAX_N + 1];    fin = fopen("range.in", "r");    fout = fopen("range.out", "w");    /*get input*/    fscanf(fin, "%d\n", &N);    for (i=0; i<N; i++)    {for (j=0; j<N; j++){    fscanf(fin, "%c", &c);    if (c == '0')    {matrix[i][j] = 0;    }    else    {matrix[i][j] = 1;    }}fscanf(fin, "%c", &c);    }    /*begin DP*/    memset(f, 0, (MAX_N + 1) * (MAX_N + 1) * sizeof(int));    for (i=N-1; i>=0; i--)    {for (j=N-1; j>=0; j--){    if (matrix[i][j] == 0)    {f[i][j] = 0;    }    else    {min = GetMin(f[i + 1][j], f[i][j + 1], f[i + 1][j + 1]);f[i][j] = min + 1;    }}    }    /*calculate the count*/    memset(count, 0, (MAX_N + 1) * sizeof(int));    for (i=0; i<N; i++)    {for (j=0; j<N; j++){    while (f[i][j] >= 2)    {count[f[i][j]--]++;    }}    }    for (i=2; i<=N; i++)    {if (count[i] != 0){    fprintf(fout, "%d %d\n", i, count[i]);}    }    return 0;}