程序逻辑就是遍历(1-n)的边长长度,以每个可能的黑点作为左上角,检验其所属正方形是否缺边,缺边就不统计。
久违的一次AC。似乎这题有很大优化空间,但是我没时间去想其他的解法,赶进度啊......
//#define LOCAL
//#define TESTING
#include<stdio.h>
#include<string.h>
#include<ctype.h>
int scnum()
{
int num;
scanf("%d", &num);
#ifdef TESTING
printf("num = %d ", num);
#endif
return num;
}
int main()
{
#ifdef LOCAL
freopen("xt4-2.in","r",stdin);
#endif
int N = 0;
for(;;)
{
N++;
int n,m,sq[10];
memset(sq,0,sizeof(sq));
scanf("%d%d", &n, &m);
char temp;
bool h[n+5][n+5],v[n+5][n+5];
memset(h,0,sizeof(h));
memset(v,0,sizeof(v));
for(int i = m; i >= 1; i--)
{
temp = getchar();
while(!isalpha(temp))
{
temp = getchar();
if( temp == EOF) break;
}
#ifdef TESTING
//printf("temp = %c\n", temp);
#endif
if(temp == 'H')
{
h[scnum()][scnum()] = true;
#ifdef TESTING
printf("h\n");
#endif
}
else if(temp == 'V')
{
v[scnum()][scnum()] = true;
#ifdef TESTING
printf("v\n");
#endif
}
}
if(getchar() == EOF) break;
#ifdef TESTING
printf("%d %d\n", n, m);
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
printf("%2d", h[i][j]);
}
printf("\n");
}
printf("-------\n");
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
printf("%2d", v[j][i]);
}
printf("\n");
}
#endif
for(int i = 1; i <= n; i++)//依次统计边长为i(1-n)的正方形
{
for(int j = 1; j <= n-i; j++)//统计点横坐标
{
for(int k = 1; k <= n - i; k++)//统计点纵坐标
{
bool ok=true;
for(int l = 0; l < i; l++)
{
if(!h[j][k+l]||!h[j+i][k+l]||!v[k][j+l]||!v[k+i][j+l])
{
ok = false;
break;
}
}
if(ok) sq[i]++;
}
}
}
//输出
if(N>1) printf("\n**********************************\n\n");
printf("Problem #%d\n\n",N);
int tot=0;
for(int i = 1; i <= n; i++) tot+=sq[i];
if(!tot) printf("No completed squares can be found.\n");
else
{
for(int i = 1; i <= n; i++) if(sq[i]) printf("%d square (s) of size %d\n", sq[i], i);
}
#ifdef TESTING
printf("\n\n");
#endif
}
return 0;
}