結果
| 問題 |
No.850 企業コンテスト2位
|
| コンテスト | |
| ユーザー |
lumc_
|
| 提出日時 | 2019-07-05 22:31:36 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 38 ms / 2,000 ms |
| コード長 | 5,869 bytes |
| コンパイル時間 | 1,651 ms |
| コンパイル使用メモリ | 121,800 KB |
| 実行使用メモリ | 25,604 KB |
| 平均クエリ数 | 200.11 |
| 最終ジャッジ日時 | 2024-07-16 17:23:50 |
| 合計ジャッジ時間 | 4,119 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 27 |
ソースコード
// includes {{{
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<tuple>
#include<cmath>
#include<random>
#include<cassert>
#include<bitset>
#include<cstdlib>
// #include<deque>
// #include<multiset>
// #include<cstring>
// #include<bits/stdc++.h>
// }}}
using namespace std;
using ll = long long;
// #undef DEBUG
// #define DEBUG
// DEBUG {{{
#include <array>
#include <deque>
#include <iostream>
#include <list>
#include <queue>
#include <stack>
#include <tuple>
#include <valarray>
#include <vector>
template < int n, class... T >
typename std::enable_if< (n >= sizeof...(T)) >::type __output_tuple(
std::ostream &, std::tuple< T... > const &) {}
template < int n, class... T >
typename std::enable_if< (n < sizeof...(T)) >::type __output_tuple(
std::ostream &os, std::tuple< T... > const &t) {
os << (n == 0 ? "" : ", ") << std::get< n >(t);
__output_tuple< n + 1 >(os, t);
}
template < class... T >
std::ostream &operator<<(std::ostream &os, std::tuple< T... > const &t) {
os << "(";
__output_tuple< 0 >(os, t);
os << ")";
return os;
}
template < class T, class U >
std::ostream &operator<<(std::ostream &os, std::pair< T, U > const &p) {
os << "(" << p.first << ", " << p.second << ")";
return os;
}
template < class T >
std::ostream &operator<<(std::ostream &os, const std::stack< T > &a) {
os << "{";
for(auto tmp = a; tmp.size(); tmp.pop())
os << (a.size() == tmp.size() ? "" : ", ") << tmp.top();
os << "}";
return os;
}
template < class T, class Container, class Compare >
std::ostream &operator<<(std::ostream &os,
std::priority_queue< T, Container, Compare > a) {
os << "{ (top) ";
while(a.size()) os << a.top() << (a.size() == 1 ? "" : ", "), a.pop();
os << " }";
return os;
}
template < class T, class Container >
std::ostream &operator<<(std::ostream &os, std::queue< T, Container > a) {
os << "{ ";
while(a.size()) os << a.front() << (a.size() == 1 ? "" : ", "), a.pop();
os << " }";
return os;
}
#ifdef DEBUG
#if !defined(DEBUG_OUT)
#define DEBUG_OUT std::cerr
#endif
#define dump(...) \
[&]() { \
auto __debug_tap = std::make_tuple(__VA_ARGS__); \
DEBUG_OUT << "[" << __LINE__ << "] " << #__VA_ARGS__ << " = " << __debug_tap \
<< std::endl; \
}()
template < class T >
inline void dump2D(T &d, size_t sizey, size_t sizex) {
for(size_t i = 0; i < sizey; i++) {
DEBUG_OUT << "\t";
for(size_t j = 0; j < sizex; j++)
DEBUG_OUT << d[i][j] << (j + 1 == sizex ? "" : "\t");
DEBUG_OUT << std::endl;
}
}
template < class T >
inline void dump1D(T &d, size_t sizey) {
for(size_t i = 0; i < sizey; i++) {
DEBUG_OUT << d[i] << (i + 1 == sizey ? "" : " ");
}
DEBUG_OUT << std::endl;
}
template <
class T, class = typename std::iterator_traits< decltype(begin(T())) >::value_type,
class = typename std::enable_if< !std::is_same< T, std::string >::value >::type >
std::ostream &operator<<(std::ostream &os, const T &a) {
os << "{";
for(auto ite = begin(a); ite != end(a); ++ite)
os << (ite == begin(a) ? "" : ", ") << *ite;
os << "}";
return os;
}
#else
#define dump(...) ((void) 42)
#define dump2D(...) ((void) 42)
#define dump1D(...) ((void) 42)
template <
class T, class = typename std::iterator_traits< decltype(begin(T())) >::value_type,
class = typename std::enable_if< !std::is_same< T, std::string >::value >::type >
std::ostream &operator<<(std::ostream &os, const T &a) {
for(auto ite = begin(a); ite != end(a); ++ite)
os << (ite == begin(a) ? "" : " ") << *ite;
return os;
}
#endif
// }}}
int n;
// 二番目に小さい
vector<int> v;
// is x < y
bool ask(int x, int y) {
#ifdef DEBUG
static bool f = 0;
if(!f){
v.resize(n + 1);
f = 1;
iota(begin(v) + 1, end(v), 1);
static random_device rnd;
static mt19937 mt(rnd());
shuffle(begin(v) + 1, end(v), mt);
dump(v);
}
return v[x] < v[y];
#endif
static int num = 0;
num++;
if(num > 334) assert(0);
cout << "? " << x << " " << y << endl;
int s;
cin >> s;
if(s == x) return true;
else return false;
}
void ans(int x) {
#ifdef DEBUG
dump(v[x]);
#endif
cout << "! " << x << endl;
exit(0);
}
int main() {
// int n = 300;
// for(int m = 2; m <= 50; m++) {
// int x = n - 1 + m - 1 + ceil(log2((n + m - 1) / m)) - 1;
// dump(m, x);
// }
cin >> n;
vector<int> v(n + 1);
iota(v.begin(), v.end(), 0);
vector<int> pars;
vector<vector<int>*> secs;
for(int i = 1; i <= n; i += 2) {
if(i+1 <= n) {
if(!ask(v[i], v[i+1])) swap(v[i], v[i+1]); // v[i] < v[i+1]
pars.push_back(v[i]);
vector<int>* vp = new vector<int>({v[i+1]});
secs.push_back(vp);
} else {
pars.push_back(v[i]);
secs.push_back(new vector<int>);
}
}
while(pars.size() >= 2) {
assert(pars.size() == secs.size());
int k = pars.size();
vector<int> newpars;
vector<vector<int>*> newsecs;
for(int i = 0; i < k; i+=2) {
if(i+1 < k) {
if(!ask(pars[i], pars[i+1])) swap(pars[i], pars[i+1]), swap(secs[i], secs[i+1]); // pars[i] < pars[i+1]
newpars.push_back(pars[i]);
newsecs.push_back(secs[i]);
newsecs.back()->push_back(pars[i+1]);
} else {
newpars.push_back(pars[i]);
newsecs.push_back(secs[i]);
}
}
pars = newpars;
secs = newsecs;
}
int mini = n + 1;
for(auto e : *secs.back()) {
if(mini == n + 1) mini = e;
else mini = ask(mini, e) ? mini : e;
}
ans(mini);
return 0;
}
lumc_