J'ai essayé this Codejam problem et j'ai produit une solution valide en C++. Il y a un Python solution sur le site Web. Se demandait si des personnes C++ offriraient des améliorations/optimisations à cette solution. Merci!Google Codejam 2009 Problème de qualification: bassin hydrographique en C++
BTW: Dans Codejam le but est d'écrire du code aussi vite que possible (une raison pour laquelle Python aurait été un meilleur choix de langue) mais je suis intéressé par l'amélioration de la solution.
#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>
#include <assert.h>
#include <stdlib.h>
// Watershed Practice Problem
// http://code.google.com/codejam/contest/dashboard?c=90101#s=p1
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;
// North.
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;
}
// West.
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;
}
// East.
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;
}
// South.
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]) {
// We are draining into an existing basin; use its label.
if (label_map[(n_i*width) + n_j] != '-')
label = label_map[(n_i*width) + n_j];
else // Drain into the neighboring cell with the smallest altitude.
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;
// The first line contains the number of maps.
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); // Line should have two numbers: W H.
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];
// Populate the altitude map and initialize the label map.
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';
// Populate the labels.
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;
}
// vim:set sw=2 sts=2 ts=2:
Voulez-vous des solutions qui fonctionnent plus rapidement ou ceux qui ont l'air plus agréable? – Tronic
Que diriez-vous des deux? :) –
Les lignes 'int altitude_map [hauteur * largeur];' et 'char label_map [hauteur * largeur]; 'ne sont pas standard C++ – Manuel