All IOI entries
Competitive Programming

IOI 2011 - Hottest (Hot)

Given N measurement points in the plane, each at (x_i, y_i) with temperature t_i, find a circle of radius R that maximizes the average temperature of enclosed points. Output the center of such a circle.

Source sync Apr 19, 2026
Track IOI
Year 2011
Files TeX and C++
Folder competitive_programming/ioi/2011/hottest
IOI2011TeXC++

Source-first archive entry

This page is built from the copied files in competitive_programming/ioi/2011/hottest. Edit competitive_programming/ioi/2011/hottest/solution.tex to update the written solution and competitive_programming/ioi/2011/hottest/solution.cpp to update the implementation.

The website does not replace those files with hand-maintained HTML. It reads the copied source tree during the build and exposes the exact files below.

Problem Statement

Rendered from the "Problem Summary" section inside solution.tex because this entry has no separate statement file.

Given $N$ measurement points in the plane, each at $(x_i, y_i)$ with temperature $t_i$, find a circle of radius $R$ that maximizes the average temperature of enclosed points. Output the center of such a circle.

Editorial

Rendered from the copied solution.tex file. The original TeX source remains available below.

Solution

Key Observation

The optimal circle must have at least one measurement point on or near its boundary, or two points defining its boundary. Therefore, the set of candidate centers is:

  1. Each measurement point itself.

  2. For each pair of points within distance $2R$, the two centers of circles of radius $R$ passing through both points.

Algorithm

For each candidate center $(c_x, c_y)$, compute the average temperature of all points within distance $R$. Return the center with the highest average.

For two points $(x_i, y_i)$ and $(x_j, y_j)$ with distance $d \le 2R$, the two candidate centers lie at: \[ \left(\frac{x_i + x_j}{2} \pm h \cdot \frac{-(y_j - y_i)}{d},\; \frac{y_i + y_j}{2} \pm h \cdot \frac{x_j - x_i}{d}\right) \] where $h = \sqrt{R^2 - d^2/4}$.

Complexity

  • Time: $O(N^3)$ --- $O(N^2)$ candidate centers, each evaluated in $O(N)$.

  • Space: $O(N)$.

  • For larger $N$, an $O(N^2 \log N)$ angular sweep can be used: for each point $i$, compute the angular intervals of centers that include each other point $j$ (with $d_{ij} \le 2R$), then sweep to find the maximum weighted count.

Implementation

#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int N;
    double R;
    cin >> N >> R;

    vector<double> x(N), y(N), t(N);
    for (int i = 0; i < N; i++)
        cin >> x[i] >> y[i] >> t[i];

    double bestAvg = -1e18;
    double bestCx = 0, bestCy = 0;

    auto eval = [&](double cx, double cy) {
        double sumT = 0;
        int cnt = 0;
        for (int i = 0; i < N; i++) {
            double dx = x[i] - cx, dy = y[i] - cy;
            if (dx*dx + dy*dy <= R*R + 1e-9) {
                sumT += t[i];
                cnt++;
            }
        }
        if (cnt > 0) {
            double avg = sumT / cnt;
            if (avg > bestAvg) {
                bestAvg = avg;
                bestCx = cx;
                bestCy = cy;
            }
        }
    };

    // Candidate 1: each point as center
    for (int i = 0; i < N; i++)
        eval(x[i], y[i]);

    // Candidate 2: pairs of points on boundary
    for (int i = 0; i < N; i++) {
        for (int j = i + 1; j < N; j++) {
            double dx = x[j] - x[i], dy = y[j] - y[i];
            double d2 = dx*dx + dy*dy;
            if (d2 > 4*R*R + 1e-9) continue;

            double mx = (x[i] + x[j]) / 2;
            double my = (y[i] + y[j]) / 2;
            double h = sqrt(max(0.0, R*R - d2/4));
            double len = sqrt(d2);
            if (len < 1e-12) continue;

            double px = -dy / len, py = dx / len;
            eval(mx + h * px, my + h * py);
            eval(mx - h * px, my - h * py);
        }
    }

    cout << fixed << setprecision(6) << bestCx << " " << bestCy << "\n";
    return 0;
}

Code

Exact copied C++ implementation from solution.cpp.

C++ competitive_programming/ioi/2011/hottest/solution.cpp

Exact copied implementation source.

Raw file
#include <bits/stdc++.h>
using namespace std;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int N;
    double R;
    cin >> N >> R;

    vector<double> x(N), y(N), t(N);
    for(int i = 0; i < N; i++){
        cin >> x[i] >> y[i] >> t[i];
    }

    double bestAvg = -1e18;
    double bestCx = 0, bestCy = 0;

    // For each point as center, compute average
    auto evalCenter = [&](double cx, double cy) {
        double sumT = 0;
        int cnt = 0;
        for(int i = 0; i < N; i++){
            double dx = x[i] - cx, dy = y[i] - cy;
            if(dx*dx + dy*dy <= R*R + 1e-9){
                sumT += t[i];
                cnt++;
            }
        }
        if(cnt > 0){
            double avg = sumT / cnt;
            if(avg > bestAvg){
                bestAvg = avg;
                bestCx = cx; bestCy = cy;
            }
        }
    };

    // Try each point as center
    for(int i = 0; i < N; i++){
        evalCenter(x[i], y[i]);
    }

    // Try each pair of points on boundary
    for(int i = 0; i < N; i++){
        for(int j = i + 1; j < N; j++){
            double dx = x[j] - x[i], dy = y[j] - y[i];
            double d2 = dx*dx + dy*dy;
            if(d2 > 4*R*R + 1e-9) continue;

            double mx = (x[i] + x[j]) / 2;
            double my = (y[i] + y[j]) / 2;
            double h = sqrt(max(0.0, R*R - d2/4));

            // Perpendicular direction
            double px = -dy, py = dx;
            double len = sqrt(px*px + py*py);
            if(len < 1e-12) continue;
            px /= len; py /= len;

            // Two candidate centers
            evalCenter(mx + h * px, my + h * py);
            evalCenter(mx - h * px, my - h * py);
        }
    }

    cout << fixed << setprecision(6) << bestCx << " " << bestCy << "\n";
    return 0;
}

Source Files

Exact copied source-of-truth files. Edit solution.tex for the write-up and solution.cpp for the implementation.

TeX write-up competitive_programming/ioi/2011/hottest/solution.tex

Exact copied write-up source.

Raw file
\documentclass[11pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[margin=1in]{geometry}
\usepackage{amsmath,amssymb,amsthm}
\usepackage{listings}
\usepackage{xcolor}
\usepackage{hyperref}

\newtheorem{theorem}{Theorem}
\newtheorem{lemma}[theorem]{Lemma}

\lstset{
  language=C++,
  basicstyle=\ttfamily\small,
  keywordstyle=\color{blue}\bfseries,
  commentstyle=\color{green!60!black},
  stringstyle=\color{red!70!black},
  numbers=left,
  numberstyle=\tiny\color{gray},
  breaklines=true,
  frame=single,
  tabsize=4,
  showstringspaces=false
}

\title{IOI 2011 -- Hottest (Hot)}
\author{Solution}
\date{}

\begin{document}
\maketitle

\section{Problem Summary}
Given $N$ measurement points in the plane, each at $(x_i, y_i)$ with temperature $t_i$, find a circle of radius $R$ that maximizes the average temperature of enclosed points. Output the center of such a circle.

\section{Solution}

\subsection{Key Observation}
The optimal circle must have at least one measurement point on or near its boundary, or two points defining its boundary. Therefore, the set of candidate centers is:
\begin{enumerate}
    \item Each measurement point itself.
    \item For each pair of points within distance $2R$, the two centers of circles of radius~$R$ passing through both points.
\end{enumerate}

\subsection{Algorithm}
For each candidate center $(c_x, c_y)$, compute the average temperature of all points within distance~$R$. Return the center with the highest average.

For two points $(x_i, y_i)$ and $(x_j, y_j)$ with distance $d \le 2R$, the two candidate centers lie at:
\[
\left(\frac{x_i + x_j}{2} \pm h \cdot \frac{-(y_j - y_i)}{d},\;
      \frac{y_i + y_j}{2} \pm h \cdot \frac{x_j - x_i}{d}\right)
\]
where $h = \sqrt{R^2 - d^2/4}$.

\subsection{Complexity}
\begin{itemize}
    \item \textbf{Time:} $O(N^3)$ --- $O(N^2)$ candidate centers, each evaluated in $O(N)$.
    \item \textbf{Space:} $O(N)$.
\end{itemize}

For larger $N$, an $O(N^2 \log N)$ angular sweep can be used: for each point~$i$, compute the angular intervals of centers that include each other point~$j$ (with $d_{ij} \le 2R$), then sweep to find the maximum weighted count.

\section{Implementation}

\begin{lstlisting}
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int N;
    double R;
    cin >> N >> R;

    vector<double> x(N), y(N), t(N);
    for (int i = 0; i < N; i++)
        cin >> x[i] >> y[i] >> t[i];

    double bestAvg = -1e18;
    double bestCx = 0, bestCy = 0;

    auto eval = [&](double cx, double cy) {
        double sumT = 0;
        int cnt = 0;
        for (int i = 0; i < N; i++) {
            double dx = x[i] - cx, dy = y[i] - cy;
            if (dx*dx + dy*dy <= R*R + 1e-9) {
                sumT += t[i];
                cnt++;
            }
        }
        if (cnt > 0) {
            double avg = sumT / cnt;
            if (avg > bestAvg) {
                bestAvg = avg;
                bestCx = cx;
                bestCy = cy;
            }
        }
    };

    // Candidate 1: each point as center
    for (int i = 0; i < N; i++)
        eval(x[i], y[i]);

    // Candidate 2: pairs of points on boundary
    for (int i = 0; i < N; i++) {
        for (int j = i + 1; j < N; j++) {
            double dx = x[j] - x[i], dy = y[j] - y[i];
            double d2 = dx*dx + dy*dy;
            if (d2 > 4*R*R + 1e-9) continue;

            double mx = (x[i] + x[j]) / 2;
            double my = (y[i] + y[j]) / 2;
            double h = sqrt(max(0.0, R*R - d2/4));
            double len = sqrt(d2);
            if (len < 1e-12) continue;

            double px = -dy / len, py = dx / len;
            eval(mx + h * px, my + h * py);
            eval(mx - h * px, my - h * py);
        }
    }

    cout << fixed << setprecision(6) << bestCx << " " << bestCy << "\n";
    return 0;
}
\end{lstlisting}

\end{document}