Codeforces Round #838 (Div. 2) D. GCD Queries (数学,交互)

题目链接:https://codeforces.com/problemset/problem/1762/D

 

 大致题意: 这是一个交互题,有一个看不见的(0-n-1)的序列,每个位置上的数我们都不知道;

    此时,我们可以询问的最多2n个问题,输出(i,j),可以得到 i 位置和 j 位置上面的数的gcd;

    然后我们需要输出俩个下标,其中一个下标所对应的数是0;

 

解题思路:可以注意到,gcd(x,0) = gcd(0,x) = x;

    而除了0以外,对于任意的y>0,gcd(x,y)<=x;

 

    现在我们考虑有三个数,x,y,i;

    如果 i = 0:

    gcdx =gcd(x,i),gcdy = (y,i);

    因为x和y是不会相等的,所以gcdx和gcdy必然不相等,此时必然有一个数大;

    如果x = 0:

    gcdx =gcd(x,i),gcdy = gcd(y,i);

    那么gcdx>=gcdy;

    y=0与x同理,我们观察可以发现,如果x,y,i里面有0,那么0所在的gcd是最大;

于是,此题就可以解决了;

时间复杂度:O(n);

 

ac代码:

#include<bits/stdc++.h>

int main()
{
    std::ios::sync_with_stdio(false); std::cin.tie(0); std::cout.tie(0);

    int T; std::cin >> T;
    while (T--)
    {
        int n; std::cin >> n;
        int L = 1, R = 2, MID, WID, ans;
        for (int i = 3; i <= n; ++i)
        {
            std::cout << "? " << L << " " << i << std::endl; std::cin >> MID;
            std::cout << "? " << R << " " << i << std::endl; std::cin >> WID;
            if (MID > WID)R = i;
            if (WID > MID)L = i;
        }
        std::cout << "! " << L << " " << R << std::endl; std::cin >> ans;
    }

    return 0;
}

这道题,其实说难不难,说简单也补简单,重点还是需要牢牢抓住0的gcd这个性质(笑

posted @ 2023-02-03 18:58  XiCen  阅读(264)  评论(0)    收藏  举报