Submission #302691

#TimeUsernameProblemLanguageResultExecution timeMemory
302691user202729Towns (IOI15_towns)C++17
Compilation error
0 ms0 KiB
// moreflags=grader.cpp
// really, who includes .c files in a .cpp one?

// ...
// definitely not an excuse for not learning classical algorithms properly.
#include "towns.h"
#include<vector>

int hubDistance(int number, int sub) {
	int const A=0;
	std::vector<int> distanceA(number);
	for(int other=1; other<number; ++other)
		distanceA[other]=getDistance(A, other);

	int const B=int(std::max_element(begin(distanceA), end(distanceA))-distanceA.begin());
	std::vector<int> distanceB(number);
	auto const diameter=distanceB[A]=distanceA[B];
	for(int other=1; other<number; ++other) if(other!=B)
		distanceB[other]=getDistance(B, other);

	// distance from B -> [(distance from path AB, node index)...]
	std::map<int, std::vector<std::pair<int, int>>> groups;
	for(int node=0; node<number; ++node){
		auto const first=distanceA[node], sec=distanceB[node];
		assert((first+sec+diameter)%2==0);
		groups[(sec+diameter-first)>>1].push_back({(first+sec-diameter)>>1, node});
	}
	assert(groups.at(0)==std::vector<int>{A});
	assert(groups.at(diameter)==std::vector<int>{B}); // <-- technically have side effects
	// (memory allocation and deallocation)

	int radius=INT_MAX, hub=-1, hubDistanceB; bool LRbalanced=false;
	{
		int sumLeftGroupSize=0; // exclude current group. Only count leaves
		int lastNode=-1, lastGroupSize, lastr, lastDistanceB;
		for(auto const& [distanceB, group]: groups){
			auto const [distancePath, node]=*std::min_element(begin(group), end(group));
			auto const r=std::max(distanceB, diameter-distanceB); // only correct for nodes on some diameter

			assert(distancePath==0); // node is on AB path
			if(distanceB*2>=diameter){
				// node and lastNode are on some diameter
				// but the next node might not be
				// compare node and lastNode. One of them is the hub
				assert(lastNode>=0);

				radius=std::min(lastr, r);
				bool const lastLRBalanced=
					std::max(sumLeftGroupSize-lastGroupSize, number-sumLeftGroupSize)
					<=number/2;
				bool const curLRBalanced=
					std::max(sumLeftGroupSize, number-sumLeftGroupSize-(int)group.size())
					<=number/2;
				assert(not (lastLRBalanced and curLRBalanced));

				if(radius==lastr){
					assert(not LRbalanced);
					hub=lastNode; hubDistanceB=lastDistanceB; LRbalanced=lastLRBalanced;
				}
				if(radius==r and curLRBalanced>=LRbalanced){ // if there are two, use the LRbalanced one
					hub=node; hubDistanceB=distanceB; LRbalanced=curLRBalanced;
				}

				break;
			}
			lastNode=node; lastGroupSize=(int)group.size(); lastr=r; lastDistanceB=distanceB;
			sumLeftGroupSize+=(int)group.size();
		}
	}

	assert(radius!=INT_MAX);
	if(sub<3){
		return radius;
	}
}

Compilation message (stderr)

towns.cpp: In function 'int hubDistance(int, int)':
towns.cpp:15:23: error: 'max_element' is not a member of 'std'; did you mean 'tuple_element'?
   15 |  int const B=int(std::max_element(begin(distanceA), end(distanceA))-distanceA.begin());
      |                       ^~~~~~~~~~~
      |                       tuple_element
towns.cpp:22:7: error: 'map' is not a member of 'std'
   22 |  std::map<int, std::vector<std::pair<int, int>>> groups;
      |       ^~~
towns.cpp:8:1: note: 'std::map' is defined in header '<map>'; did you forget to '#include <map>'?
    7 | #include<vector>
  +++ |+#include <map>
    8 | 
towns.cpp:22:11: error: expected primary-expression before 'int'
   22 |  std::map<int, std::vector<std::pair<int, int>>> groups;
      |           ^~~
towns.cpp:25:3: error: 'assert' was not declared in this scope
   25 |   assert((first+sec+diameter)%2==0);
      |   ^~~~~~
towns.cpp:8:1: note: 'assert' is defined in header '<cassert>'; did you forget to '#include <cassert>'?
    7 | #include<vector>
  +++ |+#include <cassert>
    8 | 
towns.cpp:26:3: error: 'groups' was not declared in this scope
   26 |   groups[(sec+diameter-first)>>1].push_back({(first+sec-diameter)>>1, node});
      |   ^~~~~~
towns.cpp:28:9: error: 'groups' was not declared in this scope
   28 |  assert(groups.at(0)==std::vector<int>{A});
      |         ^~~~~~
towns.cpp:28:2: error: 'assert' was not declared in this scope
   28 |  assert(groups.at(0)==std::vector<int>{A});
      |  ^~~~~~
towns.cpp:28:2: note: 'assert' is defined in header '<cassert>'; did you forget to '#include <cassert>'?
towns.cpp:32:13: error: 'INT_MAX' was not declared in this scope
   32 |  int radius=INT_MAX, hub=-1, hubDistanceB; bool LRbalanced=false;
      |             ^~~~~~~
towns.cpp:8:1: note: 'INT_MAX' is defined in header '<climits>'; did you forget to '#include <climits>'?
    7 | #include<vector>
  +++ |+#include <climits>
    8 | 
towns.cpp:36:36: warning: declaration of 'distanceB' shadows a previous local [-Wshadow]
   36 |   for(auto const& [distanceB, group]: groups){
      |                                    ^
towns.cpp:16:19: note: shadowed declaration is here
   16 |  std::vector<int> distanceB(number);
      |                   ^~~~~~~~~
towns.cpp:37:42: error: 'min_element' is not a member of 'std'
   37 |    auto const [distancePath, node]=*std::min_element(begin(group), end(group));
      |                                          ^~~~~~~~~~~
towns.cpp:37:54: error: 'begin' was not declared in this scope; did you mean 'std::begin'?
   37 |    auto const [distancePath, node]=*std::min_element(begin(group), end(group));
      |                                                      ^~~~~
      |                                                      std::begin
In file included from /usr/include/c++/9/vector:69,
                 from towns.cpp:7:
/usr/include/c++/9/bits/range_access.h:105:37: note: 'std::begin' declared here
  105 |   template<typename _Tp> const _Tp* begin(const valarray<_Tp>&);
      |                                     ^~~~~
towns.cpp:37:68: error: 'end' was not declared in this scope; did you mean 'std::end'?
   37 |    auto const [distancePath, node]=*std::min_element(begin(group), end(group));
      |                                                                    ^~~
      |                                                                    std::end
In file included from /usr/include/c++/9/vector:69,
                 from towns.cpp:7:
/usr/include/c++/9/bits/range_access.h:107:37: note: 'std::end' declared here
  107 |   template<typename _Tp> const _Tp* end(const valarray<_Tp>&);
      |                                     ^~~
towns.cpp:58:6: error: 'hub' was not declared in this scope; did you mean 'sub'?
   58 |      hub=lastNode; hubDistanceB=lastDistanceB; LRbalanced=lastLRBalanced;
      |      ^~~
      |      sub
towns.cpp:58:20: error: 'hubDistanceB' was not declared in this scope; did you mean 'hubDistance'?
   58 |      hub=lastNode; hubDistanceB=lastDistanceB; LRbalanced=lastLRBalanced;
      |                    ^~~~~~~~~~~~
      |                    hubDistance
towns.cpp:61:6: error: 'hub' was not declared in this scope; did you mean 'sub'?
   61 |      hub=node; hubDistanceB=distanceB; LRbalanced=curLRBalanced;
      |      ^~~
      |      sub
towns.cpp:61:16: error: 'hubDistanceB' was not declared in this scope; did you mean 'hubDistance'?
   61 |      hub=node; hubDistanceB=distanceB; LRbalanced=curLRBalanced;
      |                ^~~~~~~~~~~~
      |                hubDistance