QOJ.ac

QOJ

时间限制: 2 s 内存限制: 512 MB 总分: 100 难度: [显示] 交互 可 Hack ✓

#24228. Želé

统计

Tato úloha je interaktivní.

Na pultu cukrárny Blecha stojí dvě řady pestrobarevných dvouvrstvých želé (horní vrstva je $a$, dolní vrstva je $b$). Podle místního pravidla „doplňkového tuhnutí“ je součet výšek horní a dolní vrstvy každého želé přesně $n+1$. Obsluha původně uspořádala obě řady podle výšek do dokonalých permutací $1 \sim n$, ale včera večer čilá bleší obsluha omylem na některých pozicích prohodila horní a dolní vrstvu!

Nyní se blíží zahájení každoročního festivalu sladkostí a obsluha musí obnovit původní uspořádání želé před prohozením (tedy posloupnost výšek horní vrstvy $a$ před prohozením).

Výšky želé nemůžete přímo pozorovat, ale můžete zadávat pokyny automatickému měřicímu zařízení cukrárny: určíte několik pozic $i$, zařízení na těchto pozicích prohodí horní a dolní vrstvu a vrátí rozdíl mezi největší a nejmenší výškou aktuální horní vrstvy (variační rozpětí) i rozdíl mezi největší a nejmenší výškou dolní vrstvy (variační rozpětí). Pozor: účinek každého prohození zůstává zachován.

Dokážete pomocí omezeného počtu prohození a měření úspěšně obnovit původní posloupnost horní vrstvy želé?


Interaktivní knihovna nejprve zvolí permutaci $p$ čísel $1\sim n$ a vytvoří permutaci $b_i=n+1-p_i$. Potom pro každý index $i$ nezávisle rozhodne, zda prohodí dvě čísla na pozici $i$. Pole získaná po těchto prohozeních označíme $a,b$. Vždy tedy platí $a_i+b_i=n+1$, ale $a,b$ již nemusí být permutacemi.

Znáte $n$, ale tato dvě pole neznáte. Můžete vybrat několik pozic a prohodit na nich $a_i,b_i$; interaktivní knihovna vám sdělí variační rozpětí obou polí po prohození. Účinek každého prohození zůstává zachován.

Vaším úkolem je obnovit pole $a$ před prvním dotazem. Odpověď se považuje za správnou i tehdy, když se vrácené pole shoduje s cílovým polem až po současném nahrazení každé jeho hodnoty $x$ hodnotou $n+1-x$.

Implementační detaily

Nemusíte a ani nesmíte implementovat funkci main.

Ve zdrojovém souboru recover.cpp musíte zahrnout hlavičkový soubor range.h a implementovat následující funkci:

std::vector<int> recover(int c, int n);
  • $c$ je číslo aktuální podúlohy; v ostrých testech má hodnotu $1,2,3,4$ a v příkladu hodnotu $0$. $n$ je délka pole. Interaktivní knihovna zavolá recover právě jednou pro každý test.
  • Návratovou hodnotou musí být pole celých čísel délky $n$, které představuje $a$ před prvním dotazem, nebo jeho doplněk získaný nahrazením všech hodnot.

Můžete volat následující funkci:

std::pair<int, int> query(const std::vector<int>& positions);
  • Indexy v positions musí být navzájem různé a patřit do $[0,n-1]$. Je dovoleno předat prázdné pole.
  • Interaktivní knihovna na každém indexu v positions právě jednou prohodí aktuální $a_i,b_i$ a poté vrátí variační rozpětí aktuálního $a$ a variační rozpětí aktuálního $b$. Prohození se mezi dotazy kumulují, ale při vracení odpovědi musíte obnovit původní pole před prohozeními.
  • Variační rozpětí je definováno jako největší hodnota pole minus jeho nejmenší hodnota. Protože vždy platí $b_i=n+1-a_i$, jsou obě variační rozpětí vždy stejná.
  • Počet volání query nesmí překročit limit $Q_{\max}$ daného testu.

Interaktivní knihovna není adaptivní: počáteční pole jsou určena již před začátkem recover a jejich volba se nemění podle vašich dotazů. Interaktivní knihovna použitá při konečném hodnocení se může lišit od poskytnuté ukázkové knihovny. Váš program nesmí číst interní data interaktivní knihovny ani přímo pracovat se standardním vstupem a výstupem.

Lokální testování

Umístěte recover.cpp, range.h a přiložený grader.cpp do stejného adresáře a přeložte je pomocí C++17:

g++ grader.cpp recover.cpp -o recover -O2 -std=c++17
./recover < ex_range1.in

První řádek, který lokální interaktivní knihovna načítá, obsahuje $c,n,Q_{\max}$; druhý řádek obsahuje permutaci $p_0,\ldots,p_{n-1}$; třetí řádek obsahuje $n$ čísel $0/1$, přičemž $1$ znamená prohození na dané pozici před začátkem interakce. Prostřednictvím parametrů funkce dostanete pouze $c,n$; permutace, příznaky prohození a limit počtu dotazů nebudou vašemu programu přímo předány.

Je-li odpověď správná, lokální interaktivní knihovna vypíše na prvním řádku Correct! a na druhém řádku Queries used: Q, kde $Q$ je počet dotazů použitých během tohoto volání. Je-li odpověď nesprávná, vypíše Wrong answer.; pokud bylo rozhraní voláno neplatným způsobem, vypíše navíc důvod chyby na standardní chybový výstup.

Příklady

Vstup 1

0 6 67
3 1 6 4 2 5
0 1 1 0 1 0

Výstup 1

Correct!
Queries used: 16

Vysvětlení

V příkladu je před začátkem interakce $a=(3,6,1,4,5,5)$; jeho doplněk získaný nahrazením všech hodnot je $(4,1,6,3,2,2)$. Vrácení kteréhokoli z těchto polí je správné. První volání query({}) vrátí $(5,5)$. Uvedený výstup odpovídá běhu přiloženého vzorového programu; různé správné programy mohou použít různé počty dotazů.

Omezení

Pro všechny testy platí $1\le n\le 500$.

Podúloha Body $n \le$ $Q_{\max} = $ Zvláštní podmínky
$1$ $10$ $20$ $50000$ Žádné
$2$ $10$ $100$ $21000$ Žádné
$3$ $40$ $500$ $50000$ Počáteční $a$ je zaručeně permutací $1 \sim n$
$4$ $40$ $500$ $50000$ Žádné

Skóre každé podúlohy se určí podle testu s nejnižším násobitelem skóre v dané podúloze; podrobnosti jsou uvedeny níže.

Hodnocení

Pokud recover vrátí nesprávnou odpověď, parametry query jsou neplatné nebo počet dotazů překročí $Q_{\max}$, získáte za daný test $0$ bodů.

Jinak získáte v podúlohách $1,2$ za daný test plný počet bodů. V podúlohách $3,4$ označme $Q$ skutečný počet dotazů použitých v daném testu. Násobitel skóre $f(Q)$ se vypočítá podle následující tabulky:

Rozsah $Q$ $f(Q)$
$Q\le5000$ $1$
$5000 < Q\le10000$ $1-\dfrac{Q-5000}{20000}$
$10000 < Q\le20000$ $\dfrac34-\dfrac{Q-10000}{40000}$
$20000 < Q\le50000$ $\dfrac12-\dfrac{Q-20000}{100000}$
$Q>50000$ $0$
$Q$ Nejvýše $5000$ $10000$ $20000$ $50000$ Více než $50000$
$f(Q)$ $100\%$ $75\%$ $50\%$ $20\%$ $0\%$

Skóre podúlohy $3$ je $40f(Q)$ a skóre podúlohy $4$ je $40f(Q)$. Konečné skóre se zaokrouhlí na $3$ desetinná místa.

Časový limit: $2\ \mathrm{s}$.

Paměťový limit: $512\ \mathrm{MiB}$.

Editorials

IDTypeStatusTitlePosted ByLast UpdatedActions
#3106EditorialOpenNew Editorial for Problem #24228wangmaruiView

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.