非常经典又考验思维的一道题, 计算网格中的正方形个数, 难点在于利用什么样的数据结构把网格表示出来
对于该题, 只分别存储每个节点处是否有横线, 竖线即可
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <string>
#include <cstring>
#include <cmath>
#include <vector>
#include <set>
#include <queue>
#include <map>
#include <list>
using namespace std;
const int MAXN = 10+1;
typedef long long LL;
int n;
/*
关键 : 1. 图的存储数据结构: 只需用两个数组分别存储每个节点处的横边和竖边即可
2. 计算时, 按正方形边长来计算, 从头开始逐个结点枚举可以组成正方形的结点数量
*/
int V[MAXN][MAXN];
int H[MAXN][MAXN];
void test(){
for(int i=1; i<=n; i++){
for(int j=1; j<n; j++)
if( V[i][j] )printf("Col %d : %d-%d\n",i,j,j+1);
}
for(int i=1; i<=n; i++){
for(int j=1; j<n; j++)
if( H[i][j] )printf("Row %d : %d-%d\n",i,j,j+1);
}
}
int main(){
int m,Case=0;
while( scanf("%d",&n)!=EOF ){
scanf("%d",&m);
memset(V,0,sizeof(V));
memset(H,0,sizeof(H));
char type;
int i,j;
for(int k=0; k<m; k++){
cin >> type >> i >> j;
if( type=='H' ){
H[i][j] = 1;
}else if( type=='V' ){
V[i][j] = 1;
}
}
// test();
if( Case>0 ) printf("\n**********************************\n\n");
printf("Problem #%d\n\n",++Case);
int sum = 0,cnt;
for(int len=1; len<n; len++){
cnt = 0;
for(int r=1; r+len<=n; r++){
for(int c=1; c+len<=n; c++){
int flag = 1;
for(int tmp=0; tmp<len; tmp++){
if( !H[r][c+tmp] || !V[c][r+tmp] ){
flag = 0;
break;
}
if( !H[r+len][c+tmp] || !V[c+len][r+tmp] ){
flag = 0;
break;
}
}
cnt+=flag;
}
}
if( cnt ) printf("%d square (s) of size %d\n",cnt,len);
sum += cnt;
}
if( sum==0 ){
printf("No completed squares can be found.\n");
}
}
return 0;
}