Problema tanque2


#1

En el problema :
http://juez.oia.unsam.edu.ar/#/task/tanque2/statement

Al tratar de subir una solucion al juez me dio este error de compilacion

In file included from /usr/include/c++/4.8/algorithm:62:0,
from tanque2.cpp:5:
/usr/include/c++/4.8/bits/stl_algo.h: In instantiation of ‘_RandomAccessIterator std::__unguarded_partition(_RandomAccessIterator, _RandomAccessIterator, const _Tp&) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<cw*, std::vector >; _Tp = cw]’:
/usr/include/c++/4.8/bits/stl_algo.h:2283:70: required from ‘_RandomAccessIterator std::__unguarded_partition_pivot(_RandomAccessIterator, _RandomAccessIterator) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<cw*, std::vector >]’
/usr/include/c++/4.8/bits/stl_algo.h:2315:54: required from ‘void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<cw*, std::vector >; _Size = int]’
/usr/include/c++/4.8/bits/stl_algo.h:5461:36: required from ‘void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<cw*, std::vector >]�

la id de la solucion es 15207

en codeblocks se compila y anda…
Si quieren que les mande el codigo, avisenme…
Alguna sugerencia? Gracias Federico

Edit:

Codigo
#include <algorithm>
#include <iostream>
#include <fstream>
#include <vector>
#define getWeight(name) w[name>>1]
#define getIndex(name) (name<<1)
#define prnt(name) cout << "Printing " << #name << " : ";printVec(name)
#define other(name) ((name)^1)
#define useFile false
using namespace std;
vector<int> e, // edges // los lados de la lista de adjacencia
                   p, // previous // la ocurrencia anterior
                   l, // last // la ultima ocurrencia
                   w, // weight // el peso de las conessiones
                   o; // filling order // el orden de llenado de los tanques
int ammNodes;
int nodeTRep;
void readInput(const char* filename){
  #if useFile
  ifstream uniqueInputSource(filename);
  #else
  #define uniqueInputSource cin
  #endif
  uniqueInputSource >> ammNodes;
  p.resize(2*(ammNodes-1),-1);
  l.resize(ammNodes+1,-1);
  for (int i=0; i<ammNodes-1; i++){
    int f,wt,to;
    uniqueInputSource>>f>>wt>>to;
    e.push_back(f);
    e.push_back(to);
    w.push_back(wt);
    p[getIndex(i)]=l[f];
    l[f]=getIndex(i);
    p[other(getIndex(i))]=l[to];
    l[to]=other(getIndex(i));
  }
  uniqueInputSource >> nodeTRep;
  #if useFile
  uniqueInputSource.close();
  #endif
  #undef uniqueInputSource
}
struct cw{
  int x=0,y=0;
  cw(int xx, int yy){
    x=xx;y=yy;
  }
  const bool operator>(const cw &in){
    return y>in.y;
  }
  const bool operator<(const cw &in){
    return y<in.y;
  }
};
vector<cw> getSortedChildren(int parent){
  int currIndex=l[parent];
  vector<cw> toSort;
  while (currIndex!=-1){
    if (currIndex%2==0) // if is the parent and not the child
      toSort.push_back(cw(e[other(currIndex)],getWeight(currIndex)));
    currIndex=p[currIndex];
  }
  sort(toSort.begin(), toSort.end());
  return toSort;
}
int currentPlace=0;
void solve(int from){
  o[currentPlace]=from;
  currentPlace--;
  vector<cw> children=getSortedChildren(from);
  for (unsigned int i=0; i<children.size(); i++){
    solve(children[i].x);
  }
}
cw finish(){
  int tankToChange=o[nodeTRep];
  vector<cw> a=getSortedChildren(tankToChange);
  if (a.size()) // if has children
    return cw(tankToChange,a[0].y-1);
  else
    return cw(tankToChange,9999); // lo mas abajo
}
void printVec(vector<int> in){
  for (unsigned int i=0; i<in.size(); i++)
    cout << in[i] << " " << flush;
  cout << endl;
}
int main()
{
  readInput("input1.in");
  o.resize(ammNodes+1,-1);
  currentPlace=ammNodes;
  solve(1);
  cw out=finish();
  cout << out.x << " " << out.y << endl;
  return 0;
}

Fui subiendo el codigo de a partes ( primero los include y luego fui agregando las funciones) y encontre que cuando agregaba el sort(), largaba ese error…

Segun este bug report en github se debe a la version de GCC( en las anteriores a 4.9.0 ) de debe poner bool operator>(const tipo& valor) probe esto y no sirvio… me largo el mismo error
Note tambien que el error de g++
from tanque2.cpp:5:
ocurre en la linea que se haya incluido <algorithm> ( si lo muevo a la linea 1, el error salta ahi…) pero si saco el sort() todo anda bien ( excepto que obtengo 0 puntos jaja )
tambien probe const bool operator>(const cw& in),const bool operator>(cw& in),const bool operator>(cw in),bool operator>(const cw& in),bool operator>(cw& in) y bool operator>(cw in), todos me dieron el mismo error


#2

No sé si va a arreglar tu problema, pero como consejo general, fijate de tener puestas las opciones del compilador que se sugieren en la wiki.

Si con eso no saltan warnings, poné el código. Si saltan warnings fijate cuáles son y cómo arreglarlos (en el link está explicado qué es lo que identifica cada warning).

Por supuesto, si sigue habiendo dudas, preguntá todo lo que haga falta :slight_smile:

Edit:

Googleando un poquito esos errores, creo que puede estar ocurriendo si estás sobrecargando operators de una clase que creaste. Si hacés eso parece que hay que estar seguro de poner \texttt{const} tanto en los argumentos como en el operator (supongo que sin pasarlo por referencia al argumento, el resto no debería hacer falta).

Ejemplo:

\texttt{ bool operator < (const TuClase &argumento)const } \\ ...

O directamente algo así creo que también debería funcionar:

\texttt{ bool operator < (TuClase argumento) } \\ ...

Por si te sirve, me estoy basando en este post, donde creo que le pasa algo parecido a los errores que ponés.

Ya que estoy, en general yo uso el siguiente patrón para sobrecargar un operator sobre una clase propia (pongo un ejemplo).

struct Intervalo
{
	tint start, end;
	Intervalo (tint ss, tint ee)
	{
		start = ss;
		end = ee;
	}
};

bool operator < (Intervalo i1, Intervalo i2)
{
	return make_pair(i1.start,i2.end) < make_pair(i2.start,i1.end); // creciente en start, decreciente por end en caso de empate
}

#3

Gracias, ahi lo pruebo…


#4

Encontré lo que falla :grinning:

Deberías cambiarlo por

#if useFile 
ifstream uniqueInputSource(filename);

La razón es que useFile siempre está definido con algún valor (ya sea true o false), entonces con #ifdef siempre estarías leyendo de archivo

Acá lo mismo, cambiar el #ifdef por un #if

(Y acordate de poner useFile en false antes de enviar al juez :wink:)

¡Éxitos!


#5

Muchas gracias, no sabia que #if podia evaluar condiciones, lo que estaba haciendo es comentando directamente esa linea, por lo que ya no estaba definido y asi usa cin.
Ahora lo cambio a #if igual, es mucho mas elegante. Gracias
Respecto al error de compilacion, persiste D:


#6

Qué raro. Si no entiendo mal con eso del ifdef en ambos lados y con useFile en false debería estar. El resto parece bien. A la tarde/noche lo miro otra vez.

Siempre estoy hablando respecto del código en Spoiler del primer post


#7

Cambialo por

bool operator>(const cw &in) const {

(Cambialo también en el otro operator)

Básicamente hay que seguir este patrón con el const


#8
Código

Buenisimo! Funciono, Muchas gracias.
Una pregunta, por que funciona asi? Asi lo evito la proxima
-Federico


#9

No sé el por qué. @santo, ¿alguna idea?

Como te dije, yo suelo usar el patrón del struct y el operator lo hago afuera.


#10

El const a la derecha de todo afecta al parámetro implícito “this”, es decir la instancia particular del struct sobre la cuál se está llamando al método. Simplemente la regla es que los comparadores no deberían modificar las cosas que comparan, así que es todo const. Si se pasa por valor en lugar de por referencia, vale sin const porque no se modifica sino que se hace copia nueva.