I tried this Codejam problem and created a valid C ++ solution. There is a Python solution on the website . I wonder if any C ++ people will offer some improvements / optimizations for this solution. Thank!
BTW: In Codejam, the goal is to write code as quickly as possible (the reason Python would be the best choice of language), but I'm interested in improving the solution.
#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>
#include <assert.h>
#include <stdlib.h>
using namespace std;
#ifdef DEBUG
static int running_time;
#endif
void SplitString(const string &s,
char delim,
vector<string> &elems) {
stringstream ss(s);
string item;
while(getline(ss, item, delim)) {
elems.push_back(item);
}
}
void PrintMap(const char map[], int height, int width) {
for (int i = 0; i < height; ++i) {
for (int j = 0; j < width; ++j) {
cout << map[(i * width) + j] << " ";
}
cout << endl;
}
}
void MinNeighbor(const int altitude_map[],
int height, int width,
int i, int j,
int & n_i, int & n_j) {
int min_altitude = altitude_map[(i * width) + j];
n_i = i;
n_j = j;
if ((i - 1) >= 0
&& altitude_map[((i - 1) * width) + j] < min_altitude) {
min_altitude = altitude_map[((i - 1) * width) + j];
n_i = i - 1;
n_j = j;
}
if ((j - 1) >= 0
&& altitude_map[(i * width) + (j - 1)] < min_altitude) {
min_altitude = altitude_map[(i * width) + (j - 1)];
n_i = i;
n_j = j - 1;
}
if ((j + 1) < width
&& altitude_map[(i * width) + (j + 1)] < min_altitude) {
min_altitude = altitude_map[(i * width) + (j + 1)];
n_i = i;
n_j = j + 1;
}
if ((i + 1) < height
&& altitude_map[((i + 1) * width) + j] < min_altitude) {
min_altitude = altitude_map[((i + 1) * width) + j];
n_i = i + 1;
n_j = j;
}
}
void Drain(const int altitude_map[],
char label_map[],
char & label,
int height, int width,
int i, int j) {
int n_i = 0;
int n_j = 0;
MinNeighbor(altitude_map, height, width, i, j, n_i, n_j);
#ifdef DEBUG
cout << endl;
cout << "The min neighbor of : (" << i << "," << j << ") ";
cout << "is (" << n_i << "," << n_j << ")" << endl;
#endif
if (altitude_map[(n_i * width) + n_j] < altitude_map[(i * width) + j]) {
if (label_map[(n_i*width) + n_j] != '-')
label = label_map[(n_i*width) + n_j];
else
Drain(altitude_map, label_map, label, height, width, n_i, n_j);
}
label_map[(i*width) + j] = label;
#ifdef DEBUG
++running_time;
#endif
}
int main(int argc, char *argv[]) {
string file_name;
if (argc < 2)
file_name = "B-tiny-practice.in";
else
file_name = argv[1];
ifstream input_file;
input_file.open(file_name.c_str());
assert(input_file.is_open());
string line;
getline(input_file, line);
int num_maps = atoi(line.c_str());
int case_num = 1;
while (case_num <= num_maps) {
assert(!input_file.eof());
getline(input_file, line);
size_t delim = line.find(" ");
int height = atoi(line.substr(0, delim).c_str());
int width = atoi(line.substr(delim + 1).c_str());
int altitude_map[height * width];
char label_map[height * width];
for (int i = 0; i < height; ++i) {
assert(!input_file.eof());
getline(input_file, line);
vector<string> row;
SplitString(line, ' ', row);
int j = 0;
for (vector<string>::const_iterator ci = row.begin();
ci != row.end(); ++ci) {
label_map[(i * width) + j] = '-';
altitude_map[(i * width) + j++] = atoi(ci->c_str());
}
}
char current_label = 'a';
for (int i = 0; i < height; ++i) {
for (int j = 0; j < width; ++j) {
if (label_map[(i * width) + j] == '-') {
char label = current_label;
Drain(altitude_map, label_map, label, height, width, i, j);
if (label == current_label)
++current_label;
}
}
}
cout << "Case #" << case_num++ << ":" << endl;
PrintMap(label_map, height, width);
#ifdef DEBUG
cout << endl << "Running Time: " << running_time << endl;
running_time = 0;
#endif
}
input_file.close();
return 0;
}