|
|
|
#include <iostream>
|
|
|
|
#include <vector>
|
|
|
|
#include <algorithm>
|
|
|
|
#include <cstring>
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
typedef vector<vector<unsigned char>> Input;
|
|
|
|
|
|
|
|
Input parse()
|
|
|
|
{
|
|
|
|
Input data;
|
|
|
|
for (string line; getline(cin, line);) {
|
|
|
|
auto i = vector<unsigned char>(line.begin(), line.end());
|
|
|
|
for_each(i.begin(), i.end(), [](unsigned char &x){ x -= '0'; });
|
|
|
|
data.push_back(i);
|
|
|
|
}
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned p1(const Input &trees)
|
|
|
|
{
|
|
|
|
int height = trees.size();
|
|
|
|
int width = trees.front().size();
|
|
|
|
|
|
|
|
// C++ is nice except when it isn't
|
|
|
|
bool (*vis)[width] = (bool (*)[width])new bool[width * height];
|
|
|
|
memset(vis, 0, sizeof(bool) * width * height);
|
|
|
|
|
|
|
|
// The corners are visible
|
|
|
|
vis[0][0] = true;
|
|
|
|
vis[height - 1][0] = true;
|
|
|
|
vis[0][width - 1] = true;
|
|
|
|
vis[height - 1][width - 1] = true;
|
|
|
|
|
|
|
|
// Determine visibility from all four directions
|
|
|
|
for (int y = 1; y < height - 1; y++) {
|
|
|
|
for (int last = -1, x = 0; x < width; x++) {
|
|
|
|
if (trees[y][x] <= last) continue;
|
|
|
|
last = trees[y][x];
|
|
|
|
vis[y][x] = true;
|
|
|
|
}
|
|
|
|
for (int last = -1, x = width - 1; x >= 0; x--) {
|
|
|
|
if (trees[y][x] <= last) continue;
|
|
|
|
last = trees[y][x];
|
|
|
|
vis[y][x] = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (int x = 1; x < width - 1; x++) {
|
|
|
|
for (int last = -1, y = 0; y < height; y++) {
|
|
|
|
if (trees[y][x] <= last) continue;
|
|
|
|
last = trees[y][x];
|
|
|
|
vis[y][x] = true;
|
|
|
|
}
|
|
|
|
for (int last = -1, y = height - 1; y >= 0; y--) {
|
|
|
|
if (trees[y][x] <= last) continue;
|
|
|
|
last = trees[y][x];
|
|
|
|
vis[y][x] = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Count 'em up
|
|
|
|
unsigned count = 0;
|
|
|
|
for (int y = 0; y < height; y++) {
|
|
|
|
for (int x = 0; x < width; x++) if (vis[y][x]) count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Debug
|
|
|
|
//for (int y = 0; y < height; y++) {
|
|
|
|
//for (int x = 0; x < width; x++) clog << (char)(vis[y][x] ? 'x' : ' ');
|
|
|
|
//clog << endl;
|
|
|
|
//}
|
|
|
|
|
|
|
|
delete vis;
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned p2(const Input &trees)
|
|
|
|
{
|
|
|
|
int height = trees.size();
|
|
|
|
int width = trees.front().size();
|
|
|
|
|
|
|
|
unsigned score = 0;
|
|
|
|
for (int y = 1; y < height - 1; y++) {
|
|
|
|
for (int x = 1; x < width - 1; x++) {
|
|
|
|
unsigned tree = trees[y][x];
|
|
|
|
|
|
|
|
// Check all four directions
|
|
|
|
unsigned cur = 1;
|
|
|
|
unsigned c;
|
|
|
|
c = 1;
|
|
|
|
for (int ny = y + 1; ny < height - 1 && trees[ny][x] < tree; ny++) c++;
|
|
|
|
cur *= c;
|
|
|
|
c = 1;
|
|
|
|
for (int ny = y - 1; ny > 0 && trees[ny][x] < tree; ny--) c++;
|
|
|
|
cur *= c;
|
|
|
|
c = 1;
|
|
|
|
for (int nx = x + 1; nx < height - 1 && trees[y][nx] < tree; nx++) c++;
|
|
|
|
cur *= c;
|
|
|
|
c = 1;
|
|
|
|
for (int nx = x - 1; nx > 0 && trees[y][nx] < tree; nx--) c++;
|
|
|
|
cur *= c;
|
|
|
|
|
|
|
|
if (cur > score) score = cur;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return score;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main()
|
|
|
|
{
|
|
|
|
auto input = parse();
|
|
|
|
cout << p1(input) << endl;
|
|
|
|
cout << p2(input) << endl;
|
|
|
|
}
|