QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#743769#9734. Identify ChordFresca#WA 4ms3820kbC++205.9kb2024-11-13 19:58:592024-11-13 19:59:01

Judging History

你现在查看的是最新测评结果

  • [2024-12-08 22:59:51]
  • hack成功,自动添加数据
  • (/hack/1274)
  • [2024-11-13 19:59:01]
  • 评测
  • 测评结果:WA
  • 用时:4ms
  • 内存:3820kb
  • [2024-11-13 19:58:59]
  • 提交

answer

#include <algorithm>
#include <cassert>
#include <cctype>
#include <iostream>
#include <map>
#include <vector>

#if __cplusplus >= 202002l
    #include <format>
#endif

#define int long long
using ull = unsigned long long;
using ll = long long;
using pii = std::pair<int, int>;

// clang-format off
ll read()
{
    ll x=0,f=1;char ch=std::cin.get();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=std::cin.get();}
    while(isdigit(ch)){x=x*10+ch-'0';ch=std::cin.get();}
    return x*f;
}
template<typename T>
void read(std::vector<T> &vr,int n){for(int i=1;i<=n;++i)vr.push_back(read());}
template<typename T>
void read(std::vector<T> &vr,int a,int b){for(int i=a;i<=b;++i)vr[i]=read();}

// clang-format on

void solve()
{
    int n = read();
    std::map<pii, int> memory;

    auto next = [&](int x, int d) -> int
    {
        x += d;
        x = (x - 1) % n + 1;
        return x;
    };

    auto pre = [&](int x, int d) -> int
    {
        x -= d;
        assert(d <= n);
        x = (x - 1 + n) % n + 1;
        return x;
    };
    auto close = [&](int a, int b) -> bool
    {
        return a == b || next(a, 1) == b || pre(a, 1) == b;
    };

    auto ask = [&](int a, int b) -> int
    {
        if (close(a, b))
            return a == b ? 0 : 1;
        if (b < a)
            std::swap(a, b);
        if (memory.contains({a, b}))
            return memory[{a, b}];
        std::cout << std::format("? {} {}", a, b) << std::endl;
        int temp;
        std::cin >> temp;
        memory[{a, b}] = temp;
        return temp;
    };

    auto ans = [&](int a, int b) -> void
    {
        std::cout << std::format("! {} {}", a, b) << std::endl;
        int sta = read();
        if (sta == -1)
            exit(0);
    };

    auto dist = [&](int a, int b) -> int
    {
        int temp = abs(b - a);
        return std::min(n - temp, temp);
    };

    auto lenth = [&](int a, int b) -> int
    {
        if (a > b)
            b += n;
        return b - a;
    };

    int fixed = 1;
    if (n <= 10)
    {
        for (int i = 1; i <= n; ++i)
            for (int j = i + 1; j <= n; ++j)
                if (i != j && next(i, 1) != j && pre(i, 1) != j && ask(i, j) == 1)
                {
                    ans(i, j);
                    return;
                }
    }
    else
        while (true)
        {
            int firstQuery = next(fixed, n / 2);
            int oppodist = ask(fixed, firstQuery);
            if (oppodist == n / 2)
            {
                fixed = next(fixed, 2);
                continue;
            }
            int needDist = dist(firstQuery, fixed) - oppodist;
            auto binarySearch = [&](int l, int r, int isRight) -> int
            {
                auto check = [&](int a) -> int
                {
                    int oriDist = dist(a, fixed);
                    int trueDist = ask(fixed, a);
                    return needDist == oriDist - trueDist;
                };
                while (r - l > 1)
                {
                    int mid = next(l, lenth(l, r) / 2);
                    if (check(mid) ^ isRight)
                        r = mid;
                    else
                        l = mid;
                }
                return (isRight ? l : r);
            };

            int oppo1dist = ask(fixed, next(firstQuery, 1));
            int oppo2dist = ask(fixed, pre(firstQuery, 1));
            needDist = std::max(dist(fixed, next(firstQuery, 1)) - oppo1dist, needDist);
            needDist = std::max(dist(fixed, pre(firstQuery, 1)) - oppo2dist, needDist);

            int idOfValley, idOfAnother1, idOfAnother2, idOfAnother3, idOfAnother4, idOfAnother5;
            if (oppo1dist > oppodist || oppodist > oppo2dist)  // left
            {
                idOfValley = binarySearch(0, firstQuery, 0);
                idOfAnother1 = pre(idOfValley, needDist + 1);
                idOfAnother2 = next(idOfValley, needDist + 2 * dist(firstQuery, idOfValley) + 1);
                idOfAnother4 = next(idOfAnother2, 1);
                idOfAnother5 = pre(idOfAnother2, 1);
                idOfAnother3 = pre(idOfAnother1, needDist + 1);
            }
            else if (oppo1dist < oppodist || oppodist < oppo2dist)  // right
            {
                idOfValley = binarySearch(firstQuery, n + 1, 1);
                idOfAnother1 = next(idOfValley, needDist + 1);
                idOfAnother2 = pre(idOfValley, needDist + 2 * dist(firstQuery, idOfValley) + 1);
                idOfAnother4 = pre(idOfAnother2, 1);
                idOfAnother5 = next(idOfAnother2, 1);
                idOfAnother3 = next(idOfAnother1, needDist + 1);
            }
            else
            {
                __builtin_unreachable();
            }
            if (!close(idOfValley, idOfAnother1) && ask(idOfValley, idOfAnother1) == 1)
            {
                ans(idOfValley, idOfAnother1);
                return;
            }
            else if (!close(idOfValley, idOfAnother3) && ask(idOfValley, idOfAnother3) == 1)
            {
                ans(idOfValley, idOfAnother3);
                return;
            }
            else if (!close(idOfValley, idOfAnother4) && ask(idOfValley, idOfAnother4) == 1)
            {
                ans(idOfValley, idOfAnother4);
                return;
            }
            else if (!close(idOfValley, idOfAnother5) && ask(idOfValley, idOfAnother5) == 1)
            {
                ans(idOfValley, idOfAnother5);
                return;
            }
            else
            {
                ans(idOfValley, idOfAnother2);
                return;
            }
        }
}

signed main()
{
#ifdef Fresca1
    freopen("in.in", "r", stdin);
    freopen("out.out", "w", stdout);
#endif
    std::cin.tie(nullptr)->sync_with_stdio(false);

    int T = read();
    while (T--)
        solve();
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1ms
memory: 3820kb

input:

2
6
2
2
2
1
1
4
1
1

output:

? 1 3
? 1 4
? 1 5
? 2 4
! 2 4
? 1 3
! 1 3

result:

ok ok (2 test cases)

Test #2:

score: -100
Wrong Answer
time: 4ms
memory: 3680kb

input:

1000
15
5
6
6
3
5
1
1
19
5
4
6
5
3
4
5
3
1
1
17
5
4
6
5
3
4
5
2
1
1
15
6
7
5
2
1
1
14
5
6
4
3
3
2
1
1
15
3
2
4
4
3
3
3
1
1
17
8
6
5
7
3
4
4
4
1
1
20
6
7
5
2
3
1
1
13
5
6
4
2
4
2
4
1
1
18
3
2
4
5
3
1
1
13
4
3
5
3
2
1
1
14
2
3
3
3
4
3
2
2
1
17
8
4
5
5
2
5
6
1
1
12
5
4
5
3
3
2
2
2
1
10
2
3
4
5
4
3
2
2
...

output:

? 1 8
? 1 9
? 1 7
? 1 4
? 1 6
? 5 8
! 8 5
? 1 10
? 1 11
? 1 9
? 1 15
? 1 12
? 1 13
? 12 18
? 5 12
? 3 12
! 12 3
? 1 9
? 1 10
? 1 8
? 1 13
? 1 11
? 1 12
? 11 16
? 4 11
? 3 11
! 11 3
? 1 8
? 1 9
? 1 7
? 1 4
? 1 3
! 3 1
? 1 8
? 1 9
? 1 7
? 1 4
? 1 6
? 1 5
? 2 5
! 5 2
? 1 8
? 1 9
? 1 7
? 1 12
? 1 10
? 9...

result:

wrong answer Wrong answer n=15, actual=13-15, guessed=1-3 (test case 152)