204 lines
6.6 KiB
C
204 lines
6.6 KiB
C
|
|
#include <stdio.h>
|
||
|
|
#include <stdlib.h>
|
||
|
|
|
||
|
|
#define MAX_DIMENSION 1024
|
||
|
|
#define MAX_REGION 1024
|
||
|
|
|
||
|
|
void fill(char **map, int x, int y, int **region, int rows, int columns);
|
||
|
|
|
||
|
|
int main() {
|
||
|
|
char c;
|
||
|
|
|
||
|
|
char **map = calloc(MAX_DIMENSION, sizeof(map[0]));
|
||
|
|
int rows = 0, columns, i = 0;
|
||
|
|
map[rows] = calloc(MAX_DIMENSION, sizeof(map[0][0]));
|
||
|
|
|
||
|
|
while ((c = getchar()) != EOF) {
|
||
|
|
map[rows][i] = c;
|
||
|
|
i++;
|
||
|
|
if (c != '\n') {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
columns = i - 1;
|
||
|
|
i = 0;
|
||
|
|
rows++;
|
||
|
|
map[rows] = calloc(MAX_DIMENSION, sizeof(map[0][0]));
|
||
|
|
}
|
||
|
|
|
||
|
|
int **visited = calloc(rows, sizeof(visited[0]));
|
||
|
|
for (i = 0; i < rows; i++) {
|
||
|
|
visited[i] = calloc(columns, sizeof(visited[0][0]));
|
||
|
|
}
|
||
|
|
int ***regions = calloc(MAX_REGION, sizeof(regions[0]));
|
||
|
|
int region_count = 0;
|
||
|
|
|
||
|
|
int cost = 0;
|
||
|
|
int cost2 = 0;
|
||
|
|
for (i = 0; i < rows; i++) {
|
||
|
|
for (int j = 0; j < columns; j++) {
|
||
|
|
if (visited[i][j]) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
// Create new region
|
||
|
|
regions[region_count] = calloc(rows, sizeof(regions[0][0]));
|
||
|
|
for (int k = 0; k < rows; k++) {
|
||
|
|
regions[region_count][k] = calloc(columns, sizeof(regions[0][0][0]));
|
||
|
|
}
|
||
|
|
|
||
|
|
// Fill new region
|
||
|
|
fill(map, i, j, regions[region_count], rows, columns);
|
||
|
|
|
||
|
|
int area = 0;
|
||
|
|
// Copy to visited
|
||
|
|
for (int k = 0; k < rows; k++) {
|
||
|
|
for (int l = 0; l < columns; l++) {
|
||
|
|
visited[k][l] |= regions[region_count][k][l];
|
||
|
|
area += regions[region_count][k][l];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
// Calculate perimeter
|
||
|
|
int perimeter = 0;
|
||
|
|
for (int k = 0; k < rows; k++) {
|
||
|
|
for (int l = 0; l < columns; l++) {
|
||
|
|
if (!regions[region_count][k][l]) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
int row;
|
||
|
|
int column;
|
||
|
|
// Up
|
||
|
|
row = k - 1;
|
||
|
|
column = l;
|
||
|
|
if (row < 0 || !regions[region_count][row][column]) {
|
||
|
|
perimeter += 1;
|
||
|
|
}
|
||
|
|
// Down
|
||
|
|
row = k + 1;
|
||
|
|
column = l;
|
||
|
|
if (row >= rows || !regions[region_count][row][column]) {
|
||
|
|
perimeter += 1;
|
||
|
|
}
|
||
|
|
// Left
|
||
|
|
row = k;
|
||
|
|
column = l + 1;
|
||
|
|
if (column >= columns || !regions[region_count][row][column]) {
|
||
|
|
perimeter += 1;
|
||
|
|
}
|
||
|
|
// Right
|
||
|
|
row = k;
|
||
|
|
column = l - 1;
|
||
|
|
if (column < 0 || !regions[region_count][row][column]) {
|
||
|
|
perimeter += 1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
cost += area * perimeter;
|
||
|
|
|
||
|
|
// Calculate perimeter task two
|
||
|
|
perimeter = 0;
|
||
|
|
for (int k = 0; k < rows; k++) {
|
||
|
|
for (int l = 0; l < columns; l++) {
|
||
|
|
if (!regions[region_count][k][l]) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (k == 0) {
|
||
|
|
if (l == 0 || !regions[region_count][k][l-1]) {
|
||
|
|
perimeter++;
|
||
|
|
}
|
||
|
|
} else if (!regions[region_count][k-1][l]) {
|
||
|
|
if (l == 0 || !regions[region_count][k][l-1] || (regions[region_count][k][l-1] && regions[region_count][k][l-1] == regions[region_count][k-1][l-1])) {
|
||
|
|
perimeter++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (k == rows - 1) {
|
||
|
|
if (l == 0 || !regions[region_count][k][l-1]) {
|
||
|
|
perimeter++;
|
||
|
|
}
|
||
|
|
} else if (!regions[region_count][k+1][l]) {
|
||
|
|
if (l == 0 || !regions[region_count][k][l-1] || (regions[region_count][k][l-1] && regions[region_count][k][l-1] == regions[region_count][k+1][l-1])) {
|
||
|
|
perimeter++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
if (l == 0) {
|
||
|
|
if (k == 0 || !regions[region_count][k-1][l]) {
|
||
|
|
perimeter++;
|
||
|
|
}
|
||
|
|
} else if (!regions[region_count][k][l-1]) {
|
||
|
|
if (k == 0 || !regions[region_count][k-1][l] || (regions[region_count][k-1][l] && regions[region_count][k-1][l] == regions[region_count][k-1][l-1])) {
|
||
|
|
perimeter++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (l == columns - 1) {
|
||
|
|
if (k == 0 || !regions[region_count][k-1][l]) {
|
||
|
|
perimeter++;
|
||
|
|
}
|
||
|
|
} else if (!regions[region_count][k][l+1]) {
|
||
|
|
if (k == 0 || !regions[region_count][k-1][l] || (regions[region_count][k-1][l] && regions[region_count][k-1][l] == regions[region_count][k-1][l+1])) {
|
||
|
|
perimeter++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
cost2 += area * perimeter;
|
||
|
|
|
||
|
|
region_count++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
printf("%i\n", cost);
|
||
|
|
printf("%i\n", cost2);
|
||
|
|
|
||
|
|
for (i = 0; i < region_count; i++) {
|
||
|
|
for (int j = 0; j < rows; j++) {
|
||
|
|
free(regions[i][j]);
|
||
|
|
}
|
||
|
|
free(regions[i]);
|
||
|
|
}
|
||
|
|
free(regions);
|
||
|
|
for (i = 0; i < rows; i++) {
|
||
|
|
free(visited[i]);
|
||
|
|
}
|
||
|
|
free(visited);
|
||
|
|
for (i = 0; i < rows + 1; i++) {
|
||
|
|
free(map[i]);
|
||
|
|
}
|
||
|
|
free(map);
|
||
|
|
}
|
||
|
|
|
||
|
|
void fill(char **map, int x, int y, int **region, int rows, int columns) {
|
||
|
|
region[x][y] = 1;
|
||
|
|
|
||
|
|
int row;
|
||
|
|
int column;
|
||
|
|
// Up
|
||
|
|
row = x - 1;
|
||
|
|
column = y;
|
||
|
|
if (row >= 0 && map[row][column] == map[x][y] && !region[row][column]) {
|
||
|
|
fill(map, row, column, region, rows, columns);
|
||
|
|
}
|
||
|
|
// Down
|
||
|
|
row = x + 1;
|
||
|
|
column = y;
|
||
|
|
if (row < rows && map[row][column] == map[x][y] && !region[row][column]) {
|
||
|
|
fill(map, row, column, region, rows, columns);
|
||
|
|
}
|
||
|
|
// Left
|
||
|
|
row = x;
|
||
|
|
column = y + 1;
|
||
|
|
if (column < columns && map[row][column] == map[x][y] && !region[row][column]) {
|
||
|
|
fill(map, row, column, region, rows, columns);
|
||
|
|
}
|
||
|
|
// Right
|
||
|
|
row = x;
|
||
|
|
column = y - 1;
|
||
|
|
if (column >= 0 && map[row][column] == map[x][y] && !region[row][column]) {
|
||
|
|
fill(map, row, column, region, rows, columns);
|
||
|
|
}
|
||
|
|
}
|