UVa 201 正方形 题解

2022-04-18

有$n$行$n$列($2\leq n\leq 9$)的小黑点,还有$m$条线段连接其中的一些黑点。统计这些线段连成了多少个正方形(每种边长分别统计)。

用二维数组表示点集,每个点显然只有四种状态,可以记为0 1 2 3。1表示连有横线,2表示连有竖线,3则两者兼有。

#include <stdio.h>
#include <string.h>
#define EH(x) (((x) == 1) || ((x) == 3))
#define EV(x) (((x) == 2) || ((x) == 3))
int is_square(int n, int b[n][n], int i, int j, int l) {
  if (b[i][j] != 3) return 0;
  for (int x = 1; x < l; x++)
    if (!(EH(b[i][j + x]) && EH(b[i + l][j + x]))) return 0;
  for (int x = 1; x < l; x++)
    if (!(EV(b[i + x][j]) && EV(b[i + x][j + l]))) return 0;
  if (!(EV(b[i][j + l]) && EH(b[i + l][j]))) return 0;
  return 1;
}
int main(void) {
  int n, m, count = 1;
  while (scanf("%d%d", &n, &m) == 2) {
    if (count > 1) printf("\n**********************************\n\n");
    int board[n][n], cnt[n];
    memset(board, 0, n * n * sizeof(int));
    memset(cnt, 0, n * sizeof(int));
    char direction;
    int i, j;
    while (m--) {
      scanf("\n%c %d %d", &direction, &i, &j);
      if (direction == 'H') board[i - 1][j - 1] += 1;
      if (direction == 'V') board[j - 1][i - 1] += 2;
    }
    printf("Problem #%d\n\n", count++);
    for (int l = 1; l < n; l++)
      for (i = 0; i < n - l; i++)
        for (j = 0; j < n - l; j++)
          if (is_square(n, board, i, j, l)) cnt[l]++;
    int flag = 0;
    for (i = 0; i < n; i++)
      if (cnt[i]) {
        flag++;
        printf("%d square (s) of size %d\n", cnt[i], i);
      }
    if (!flag) printf("No completed squares can be found.\n");
  }
  return 0;
}

吐槽一下,都什么年代了,UVa还不支持c99

几种排序算法的实现与测速

用位运算解决汉诺塔问题