QOJ.ac

QOJ

Time Limit: 2 s Memory Limit: 512 MB Total points: 100 Interactive

#1228. La exploración de I 君

Statistics

Este es un problema interactivo.

Contexto

Tras medio año, I 君 ya no puede mantener abierta su tienda. Decide traspasarla y convertirse en explorador para descubrir el vasto mundo desconocido.

Siguiendo un libro antiguo, encuentra en el corazón de un gran desierto un palacio subterráneo creado por una civilización desconocida. El palacio consta de $N$ grandes cuevas y $M$ pasadizos bidireccionales que las conectan. El libro permite a I 君 identificar la cueva en la que se encuentra, pero no describe cómo se conectan los $M$ pasadizos, por lo que le resulta difícil buscar los tesoros inagotables que, según la leyenda, esconde el palacio.

Ahora ha descubierto un mecanismo misterioso que proporciona información sobre el palacio. Decide utilizarlo para averiguar su estructura de conexiones. Ayúdalo.

Descripción

El palacio subterráneo se puede representar como un grafo simple no dirigido de $N$ vértices y $M$ aristas. En un grafo simple hay como máximo una arista directamente entre cada pareja de vértices. Las cuevas están numeradas de $0$ a $n-1$. Actualmente desconoces cuáles son las aristas.

Cada cueva tiene una fuente de luz que puede estar encendida o apagada. Una cueva solo está iluminada cuando su fuente está encendida. Inicialmente todas están apagadas, y sus estados solo pueden cambiarse mediante el mecanismo misterioso descubierto por I 君. Concretamente, permite realizar estas cuatro operaciones:

  1. Se proporciona un número $x$ y el mecanismo invierte el estado de la luz de la cueva $x$ y de todas las cuevas conectadas directamente con ella por un pasadizo: las luces encendidas se apagan y las apagadas se encienden.
  2. Se proporciona un número $x$ y el mecanismo muestra el estado actual de la luz de la cueva $x$.
  3. Se proporcionan dos números $x,y$ para indicar que has determinado que existe un pasadizo entre esas cuevas y hacer que el mecanismo lo registre.
  4. Se proporciona un número $x$ y el mecanismo comprueba si ya se han registrado todos los pasadizos conectados con la cueva $x$.

Solo se puede realizar una operación después de que haya terminado la anterior. El mecanismo no puede utilizarse libremente: los límites de uso de las cuatro operaciones son, respectivamente, $L_m,L_q,M,L_c$. Debes escribir un programa que ayude a I 君 a utilizarlo adecuadamente para encontrar correctamente los $M$ pasadizos.

Detalles de implementación

No necesitas ni debes implementar la función principal. Solo debes implementar explore(N, M), donde $N,M$ son el número de cuevas y de pasadizos. Puedes interactuar con la biblioteca mediante estas cuatro funciones:

1. modify(x)

  • Ejecuta la operación 1 del mecanismo con el número $x$.
  • Debes garantizar $0\le x<N$. La función no devuelve ningún valor.

2. query(x)

  • Ejecuta la operación 2 del mecanismo con el número $x$.
  • Debes garantizar $0\le x<N$. Devuelve $0$ o $1$, indicando que la luz de la cueva $x$ está apagada ($0$) o encendida ($1$), respectivamente.

3. report(x, y)

  • Ejecuta la operación 3 del mecanismo con los números $x,y$.
  • Debes garantizar $0\le x,y<N$ y $x\ne y$. No devuelve ningún valor.

4. check(x)

  • Ejecuta la operación 4 del mecanismo con el número $x$.
  • Debes garantizar $0\le x<N$. Devuelve $0$ o $1$, y devuelve $1$ si y solo si todos los pasadizos conectados con la cueva $x$ se han registrado mediante la operación 3.

Durante la evaluación, la biblioteca llama a explore exactamente una vez.

Se garantiza que el grafo utilizado está completamente determinado antes de comenzar la interacción y no se construye dinámicamente según la interacción con tu programa. Por tanto, todas las operaciones son deterministas y no necesitas conocer los detalles de su implementación en la biblioteca.

Se garantiza que, respetando los límites de llamadas, el tiempo de ejecución de la biblioteca no supera 1 segundo. Su consumo de memoria es fijo y no supera 128 MB.

Método de implementación

En el directorio de trabajo del concursante se proporciona template_explore.cpp/c/pas. Cópialo, renombra la copia como explore.cpp/c/pas y desarrolla tu solución a partir de ella.

Para participantes que utilicen C++ o C

  • Asegúrate de incluir #include "explore.h" al principio de tu programa.
  • La interfaz de la función explore que debes implementar es:
void explore(int N, int M);
  • Las interfaces de las funciones de interacción disponibles son:
void modify(int x);
int query(int x);
void report(int x, int y);
int check(int x);

Para participantes que utilicen Pascal

  • Atención: la sintaxis de implementación de la interfaz en Pascal es relativamente compleja. Trabaja directamente sobre el archivo proporcionado template_explore.pas, en lugar de escribir el código desde cero.
  • La interfaz de la función que debes implementar es:
procedure _explore(N, M : longint);
  • Atención: su nombre es _explore, no explore. Utilizar explore hará que falle la compilación.
  • Las interfaces de las funciones de interacción disponibles son:
procedure modify(x : longint);
function query(x : longint) : longint;
procedure report(x : longint; y : longint);
function check(x : longint) : longint;

Cómo probar el programa

Los archivos grader.cpp/c y graderhelperlib.pas del directorio del problema son implementaciones de referencia de la biblioteca de interacción. La implementación utilizada en la evaluación final difiere de ellas, por lo que tu solución no debe depender de cómo esté implementada la biblioteca.

Para participantes que utilicen C/C++

Debes compilar el ejecutable en el directorio del problema mediante estos comandos:

Para C:

gcc grader.c explore.c -o explore -O2 -lm

Para C++:

g++ grader.cpp explore.cpp -o explore -O2 -lm

Para participantes que utilicen Pascal

Debes compilar el ejecutable en el directorio del problema mediante el siguiente comando:

fpc grader.pas -o"explore" -O2

Para el ejecutable obtenido

El ejecutable lee de la entrada estándar los datos con el siguiente formato:

La primera línea contiene tres enteros $L_m,L_q,L_c$ y la segunda dos enteros $N,M$, con los significados de la descripción.

Cada una de las siguientes $M$ líneas contiene dos enteros $x,y$, que describen un pasadizo entre las cuevas $x$ e $y$.

Después de leer los datos, la biblioteca llama a explore exactamente una vez para probar tu función con ellos. Cuando tu función retorna correctamente, la biblioteca comprueba si tu cálculo es correcto. Si lo es, imprime Correct e información sobre el número de llamadas a las funciones de interacción; de lo contrario, imprime el mensaje de error correspondiente.

Ejemplo de interacción

Supongamos que el ejecutable lee los siguientes datos:

100 200 300
3 2
0 1
1 2

Los tres enteros de la primera línea indican los límites de llamadas de tres operaciones: modify(x) no puede llamarse más de 100 veces, query(x) más de 200 veces y check(x) más de 300 veces.

Los dos enteros de la segunda línea indican el número de cuevas y el de pasadizos: $N=3$, $M=2$.

El número de llamadas a report(x, y) no puede superar $M$, que en este ejemplo es 2.

El siguiente proceso de interacción es correcto:

Programa del concursante Biblioteca de interacción Nota
Llama a explore(3, 2) Comienza la prueba
Llama a modify(0) Aplica la operación 1 a la cueva $0$
Llama a query(2) Devuelve $0$ La luz de la cueva $2$ está apagada
Llama a report(0, 1) Descubre y registra el pasadizo $(0,1)$
Llama a check(0) Devuelve $1$ Todos los pasadizos de la cueva $0$ están registrados
Llama a report(2, 1) Descubre y registra el pasadizo $(2,1)$
Termina y retorna Imprime Correct en pantalla La interacción termina con un resultado correcto

Archivos proporcionados

En el directorio del problema:

  1. grader.cpp/c y graderhelperlib.pas son las implementaciones de referencia de la biblioteca de interacción.
  2. explore.h y grader.pas son archivos de cabecera; no necesitas conocer su contenido concreto.
  3. template_explore.cpp/c/pas contiene el código fuente de ejemplo proporcionado para resolver el problema.
  4. explore1.in, explore2.in, explore3.in son entradas de ejemplo que puedes utilizar para probar tu programa.

Haz copias de seguridad de todos los archivos proporcionados. El evaluador solo recoge explore.c/cpp/pas del directorio del problema; los cambios en los demás archivos no tienen efecto.

Subtareas

La evaluación final solo recoge explore.cpp/c/pas. Modificar los demás archivos del directorio del concursante no tiene efecto sobre ella.

Se aplican primero las mismas restricciones que en un problema tradicional. Por ejemplo, un error de compilación hace que todo el problema obtenga 0 puntos, y un error de ejecución o superar los límites de tiempo o memoria hace que el caso de prueba correspondiente obtenga 0 puntos. Solo puedes acceder a las variables definidas por ti y a las proporcionadas por la biblioteca, y a sus espacios de memoria correspondientes. Intentar acceder a otros espacios puede causar errores de compilación o ejecución.

Bajo esas condiciones, obtienes la puntuación completa de un caso de prueba si y solo si:

  1. Todas tus llamadas son válidas, y los números de llamadas a modify, query, check no superan $L_m,L_q,L_c$, respectivamente.
  2. Como el límite de llamadas a report es $M$, cada llamada debe registrar una arista nueva que exista. Es decir, al llamar a report(x, y) debe existir un pasadizo entre $x$ e $y$, y no se debe haber llamado antes a report(x, y) ni a report(y, x).
  3. La función explore que has implementado retorna normalmente.
  4. Cuando explore retorna, ya has registrado los $M$ pasadizos mediante llamadas a report.

Restricciones

Hay 25 casos de prueba, cada uno de 4 puntos. Los tamaños y límites correspondientes son:

Caso de prueba $N=$ $M=$ $L_m=$ $L_q=$ $L_c=$ Propiedad especial
$1$ $3$ $2$ $100$ $100$ $100$ Ninguna
$2$ $100$ $10N$ $200$ $10^4$ $2M$ Ninguna
$3$ $200$ $10N$ $200$ $4\times 10^4$ $2M$ Ninguna
$4$ $300$ $10N$ $299$ $9\times 10^4$ $2M$ Ninguna
$5$ $500$ $10N$ $499$ $1.5\times 10^5$ $2M$ Ninguna
$6$ $59998$ $N/2$ $17N$ $17N$ $0$ A
$7$ $99998$ $N/2$ $18N$ $18N$ $0$ A
$8$ $199998$ $N/2$ $19N$ $19N$ $0$ A
$9$ $199998$ $N/2$ $19N$ $19N$ $0$ A
$10$ $99997$ $N-1$ $18N$ $18N$ $0$ B
$11$ $199997$ $N-1$ $19N$ $19N$ $0$ B
$12$ $99996$ $N-1$ $10^7$ $10^7$ $2M$ C
$13$ $199996$ $N-1$ $10^7$ $10^7$ $2M$ C
$14$ $199996$ $N-1$ $10^7$ $10^7$ $2M$ C
$15$ $99995$ $N-1$ $10^7$ $10^7$ $2M$ D
$16$ $99995$ $N-1$ $10^7$ $10^7$ $2M$ D
$17$ $199995$ $N-1$ $10^7$ $10^7$ $2M$ D
$18$ $1004$ $2000$ $10^7$ $5\times 10^4$ $2M$ Ninguna
$19$ $1004$ $3000$ $10^7$ $5\times 10^4$ $2M$ Ninguna
$20$ $1004$ $3000$ $10^7$ $5\times 10^4$ $2M$ Ninguna
$21$ $50000$ $2N$ $10^7$ $10^7$ $2M$ Ninguna
$22$ $100000$ $2N$ $10^7$ $10^7$ $2M$ Ninguna
$23$ $150000$ $200000$ $10^7$ $10^7$ $2M$ Ninguna
$24$ $200000$ $250000$ $10^7$ $10^7$ $2M$ Ninguna
$25$ $200000$ $300000$ $10^7$ $10^7$ $2M$ Ninguna

Recordamos que el grafo de la prueba queda completamente determinado antes de comenzar la interacción y no se construye dinámicamente según la interacción con tu programa.

Los símbolos de la columna de propiedades especiales significan lo siguiente:

A: se garantiza que el grado de cada vértice es exactamente $1$.

B: para cada $x>0$, existe exactamente un $y<x$ tal que las cuevas $x$ e $y$ están conectadas directamente por un pasadizo.

C: existe una permutación $p_0,p_1,\ldots,p_{N-1}$ de $0$ a $N-1$ tal que, para todo $1\le i<N$, hay un pasadizo entre las cuevas $p_{i-1}$ y $p_i$.

D: se garantiza que el grafo está conectado.

  • Nota: tu programa puede distinguir los distintos tipos de datos anteriores mediante el dígito de las unidades del valor $N$ recibido.

Discussions

About Discussions

The discussion section is only for posting: General Discussions (problem-solving strategies, alternative approaches), and Off-topic conversations.

This is NOT for reporting issues! If you want to report bugs or errors, please use the Issues section below.

Open Discussions 0
No discussions in this category.

Issues

About Issues

If you find any issues with the problem (statement, scoring, time/memory limits, test cases, etc.), you may submit an issue here. A problem moderator will review your issue.

Guidelines:

  1. This is not a place to publish discussions, editorials, or requests to debug your code. Issues are only visible to you and problem moderators.
  2. Do not submit duplicated issues.
  3. Issues must be filed in English or Chinese only.
Active Issues 0
No issues in this category.
Closed/Resolved Issues 0
No issues in this category.