题目
由于防控形势严峻,现在z市已经开始了全区域的网格化封控管理。该市的区域可以看成一个矩形,其中所有主干道都是水平或垂直的,并且贯穿整个区域。如图所示,黑色表示城区的边界,红色表示城区的主干道,其中边界和主干道宽度都为1,且不存在边界与主干道、主干道与主干道相邻的情况。
为了方便网格化管理,我们定义网格单元是由城区边界或主干道围成的区域,且任意网格单元内不能包含主干道。上图中,该城区共被分割成了16个网格单元。
同时,网格化管理的本质思想是“分治”,不同的划分粒度对于管理效率会产生深远的影响。所以,这次W同学思考的不仅仅是网格单元,而是子网格。
子网格的定义为:子网格也是一个矩形,且子网格矩形4个角的对应点都位于边界与边界、边界与主干道、主干道与主干道的交点上。我们认为两个子网格是相同的,当且仅当两个子网格的4个角对应点全部重合。根据这个定义,我们可以知道,任意的网格单元也是一种子网格,整个城区的矩形也是一种特殊的子网格。
同样给出上述的图像,你能否帮小W计算下,有多少种可能的子网格?
输入格式:
第一行输入两个整数n,m(3≤n,m≤100)
其后n行,每行m个字符,字符有*
和#
两种。*
代表城区边界或主干道,#
代表网格单元内区域。
输出格式:
输出一行一个整数,代表符合条件不同子网格的个数。
输入样例:
3 7
*******
*##*##*
*******
输出样例:
3
题解
分析
我的代码
吐槽
代码运行超时了
#include<stdio.h>
#include<stdbool.h>
bool flag(int x1, int y1, int x2, int y2,char str[][1000]);
int main()
{
/*
* 主要思路:把输入的看成一个字母矩阵,从中选择矩阵
* 这个矩阵有一个要求:边上是'*',矩阵内部有'#'
*/
char str[1000][1000];
int n, m, count = 0;
scanf("%d %d", &n, &m);
for (int i = 0; i < n; i++)
{
scanf("%s", str[i]);
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
for (int k = i+2; k < n; k++)
{
for (int l = j+2; l < m; l++)
{
if (flag(i,j,k,l,str))
{
count++;
}
}
}
}
}
printf("%d", count);
return 0;
}
bool flag(int x1, int y1, int x2, int y2, char str[][1000])
{
bool a = false, b = true, c = true, isbreak = false;
for (int i = x1+1; i < x2; i++)
{
for (int j = y1+1; j < y2; j++)
{
if (str[i][j] == '#')
{
a = true;
isbreak = true;
break;
}
}
if (isbreak)
{
break;
}
}
for (int i = y1; i <= y2; i++)
{
if (str[x1][i] == '#' || str[x2][i] == '#')
{
b = false;
}
}
for (int i = x1; i <= x2; i++)
{
if (str[i][y1] == '#' || str[i][y2] == '#')
{
c = false;
}
}
if (a&&b&&c)
{
return true;
}
else
{
return false;
}
}
代码
对于第一次的代码,判断函数改成两个判断函数,不符合条件时直接return。这样就能加快运行速度了。
#include<stdio.h>
#include<stdbool.h>
bool flag_1 (int x1, int y1, int x2, int y2, char str[][1000]);
bool flag_2(int x1, int y1, int x2, int y2, char str[][1000]);
int main()
{
/*
* 主要思路:把输入的看成一个字母矩阵,从中选择矩阵
* 这个矩阵有一个要求:边上是'*',矩阵内部有'#'
*/
char str[1000][1000];
int n, m, count = 0;
scanf("%d %d", &n, &m);
for (int i = 0; i < n; i++)
{
scanf("%s", str[i]);
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
for (int k = i + 2; k < n; k++)
{
for (int l = j + 2; l < m; l++)
{
if (flag_1(i, j, k, l, str) && flag_2(i, j, k, l, str))
{
count++;
}
}
}
}
}
printf("%d", count);
return 0;
}
bool flag_1 (int x1, int y1, int x2, int y2, char str[][1000])
{
bool a = false, b = true, c = true, isbreak = false;
for (int i = x1 + 1; i < x2; i++)
{
for (int j = y1 + 1; j < y2; j++)
{
if (str[i][j] == '#')
{
return true;
}
}
}
return false;
}
bool flag_2(int x1, int y1, int x2, int y2, char str[][1000])
{
for (int i = y1; i <= y2; i++)
{
if (str[x1][i] == '#' || str[x2][i] == '#')
{
return false;
}
}
for (int i = x1; i <= x2; i++)
{
if (str[i][y1] == '#' || str[i][y2] == '#')
{
return false;
}
}
return true;
}