Submission #1305287

#TimeUsernameProblemLanguageResultExecution timeMemory
1305287otariusWorm Worries (BOI18_worm)C++20
32 / 100
11 ms4268 KiB
#include <bits/stdc++.h>
#include <bits/extc++.h>
using namespace __gnu_pbds;
using namespace std;

// #pragma GCC optimize("Ofast")
// #pragma GCC optimize ("unroll-loops")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define ff first
#define sc second
#define pb push_back
#define ll long long
#define pll pair<ll, ll>
#define pii pair<int, int>
#define ull unsigned long long
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
mt19937_64 rngl(chrono::steady_clock::now().time_since_epoch().count());

// #define int long long
// #define int unsigned long long

// #define ordered_set(T) tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>
// #define ordered_multiset(T) tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>

// const ll mod = 1e9 + 7;
// const ll mod = 998244353;

const ll inf = 1e9;
const ll biginf = 1e18;
// const int maxN;

int n, m, k, q;
const double phi = (3 - sqrt(5.0)) / 2;
int ask(int i, int j, int l) {
    if (i < 1 || i > n || j < 1 || j > m || l < 1 || l > k) return 0;
    cout << "? " << i << ' ' << j << ' ' << l << endl;
    int x; cin >> x; return x;
}
void go1() {
    int l = 1, r = n, m1, m2, arr[n + 1]{};
    m1 = 1 + floor(n * phi); m2 = n - floor(n * phi);
    while (r - l >= 5) {
        if (arr[m1] == 0) arr[m1] = ask(m1, 1, 1);
        if (arr[m2] == 0) arr[m2] = ask(m2, 1, 1);
        
        if (arr[m1] < arr[m2]) {
            l = m1; m1 = m2; m2 = r - floor((r - l + 1) * phi);
        } else {
            r = m2; m2 = m1; m1 = l + floor((r - l + 1) * phi);
        }
    }
    
    int mx = l;
    for (int i = l; i <= r; i++) {
        if (arr[i] == 0) arr[i] = ask(i, 1, 1);
        if (arr[i] > arr[mx]) mx = i;
    }
    
    cout << "! " << mx << " 1 1" << endl;
}
void go2() {
    int mxi = 1, mxj = 1, arr[n + 5][m + 5]{};
    arr[mxi][mxj] = ask(mxi, mxj, 1);
    
    int l1 = 1, r1 = n, l2 = 1, r2 = m;
    while (r1 - l1 > 3 || r2 - l2 > 3) {
        if (r1 - l1 > r2 - l2) {
            int mid = (l1 + r1) / 2, mx = l2;
            for (int i = l2; i <= r2; i++) {
                if (arr[mid][i] == 0) arr[mid][i] = ask(mid, i, 1);
                if (arr[mid][i] > arr[mid][mx]) mx = i;
            }
            
            if (arr[mid][mx] < arr[mxi][mxj]) {
                if (mid < mxi) l1 = mid + 1; else r1 = mid; continue;
            }
            
            mxi = mid; mxj = mx;
            if (arr[mxi - 1][mxj] == 0) arr[mxi - 1][mxj] = ask(mxi - 1, mxj, 1);
            if (arr[mxi + 1][mxj] == 0) arr[mxi + 1][mxj] = ask(mxi + 1, mxj, 1);
            
            if (arr[mxi][mxj] > arr[mxi - 1][mxj] && arr[mxi][mxj] > arr[mxi + 1][mxj]) {
                cout << "! " << mxi << ' ' << mxj << ' ' << 1 << endl; return;
            }
            
            if (arr[mxi - 1][mxj] > arr[mxi + 1][mxj]) r1 = mid;
            else l1 = mid;
        } else {
            int mid = (l2 + r2) / 2, mx = l1;
            for (int i = l1; i <= r1; i++) {
                if (arr[i][mid] == 0) arr[i][mid] = ask(i, mid, 1);
                if (arr[i][mid] > arr[mx][mid]) mx = i;
            }
            
            if (arr[mx][mid] < arr[mxi][mxj]) {
                if (mid < mxj) l2 = mid + 1; else r2 = mid; continue;
            }
            
            mxi = mx; mxj = mid;
            if (arr[mxi][mxj - 1] == 0) arr[mxi][mxj - 1] = ask(mxi, mxj - 1, 1);
            if (arr[mxi][mxj + 1] == 0) arr[mxi][mxj + 1] = ask(mxi, mxj + 1, 1);
            
            if (arr[mxi][mxj] > arr[mxi][mxj - 1] && arr[mxi][mxj] > arr[mxi][mxj + 1]) {
                cout << "! " << mxi << ' ' << mxj << ' ' << 1 << endl; return;
            }
            
            if (arr[mxi][mxj - 1] > arr[mxi][mxj + 1]) r2 = mid;
            else l2 = mid;
        }
    }
    
    for (int i = l1; i <= r1; i++) {
        for (int j = l2; j <= r2; j++) {
            if (arr[i][j] == 0) arr[i][j] = ask(i, j, 1);
            if (arr[i][j] >= arr[i - 1][j] && arr[i][j] >= arr[i + 1][j] && arr[i][j] >= arr[i][j - 1] && arr[i][j] >= arr[i][j + 1]) {
                cout << "! " << i << ' ' << j << ' ' << 1 << endl; return;
            }
        }
    }
    
    cout << "! " << mxi << ' ' << mxj << ' ' << 1 << endl;
}
void go3() {
    
}
void solve() {
    cin >> n >> m >> k >> q;
    if (m == 1 && k == 1) go1();
    else if (k == 1) go2();
    else go3();
}
int32_t main() { 
// #ifndef ONLINE_JUDGE
//     freopen("input.txt", "r", stdin);
//     freopen("output.txt", "w", stdout);
// #endif
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);
    
    int t = 1;
    // cin >> t;
    while (t--) {
        solve();
        cout << '\n';
    }
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...