C++ 最大元素的打印索引

C++ 最大元素的打印索引,c++,algorithm,logic,interactive,C++,Algorithm,Logic,Interactive,彼得有N个球,编号从1到N 没有两个球的重量相同。你想找到最重的球,但你不知道它是哪一个,彼得也不想把它给你。因此,他决定和你玩一个游戏 你最多可以问彼得Q=4+N/2个问题。在每个问题中,你必须给彼得五个不同球的编号,彼得告诉你这些球中第三和第四重球的编号。找到最重的球的数目 互动: 首先,您应该读取一行,其中包含一个表示测试用例数量的整数T。 对于每个测试用例,您应该从读取包含单个整数N的行开始。 要提问,您应该打印一行,其中包含字符“?”、一个空格和五个空格分隔的整数i1、i2、i3、i4

彼得有N个球,编号从1到N

没有两个球的重量相同。你想找到最重的球,但你不知道它是哪一个,彼得也不想把它给你。因此,他决定和你玩一个游戏

你最多可以问彼得Q=4+N/2个问题。在每个问题中,你必须给彼得五个不同球的编号,彼得告诉你这些球中第三和第四重球的编号。找到最重的球的数目

互动: 首先,您应该读取一行,其中包含一个表示测试用例数量的整数T。 对于每个测试用例,您应该从读取包含单个整数N的行开始。 要提问,您应该打印一行,其中包含字符“?”、一个空格和五个空格分隔的整数i1、i2、i3、i4和i5:五个不同球的数目(按任意顺序)

然后,您必须读取一行包含两个空格分隔的整数:第三和第四重球的编号

要完成测试用例的求解,请打印一行包含字符“!”,一个空格和一个整数im:最重的球的数目(1≤感应电动机≤N)

打印每行后,不要忘记刷新输出

约束条件:

You               Grader
                  1
                  6
? 1 2 3 4 5
                  3 4
? 1 2 3 4 6
                  3 4
? 1 2 3 5 6
                  3 5
? 1 2 4 5 6
                  4 5
? 1 3 4 5 6
                  4 5
? 2 3 4 5 6
                  4 5
! 6
  • 一,≤T≤一千
  • 六,≤N≤一百
示例:

You               Grader
                  1
                  6
? 1 2 3 4 5
                  3 4
? 1 2 3 4 6
                  3 4
? 1 2 3 5 6
                  3 5
? 1 2 4 5 6
                  4 5
? 1 3 4 5 6
                  4 5
? 2 3 4 5 6
                  4 5
! 6
说明:

You               Grader
                  1
                  6
? 1 2 3 4 5
                  3 4
? 1 2 3 4 6
                  3 4
? 1 2 3 5 6
                  3 5
? 1 2 4 5 6
                  4 5
? 1 3 4 5 6
                  4 5
? 2 3 4 5 6
                  4 5
! 6
球按重量的降序排列

这是对codechef竞赛中一个问题的解释,因为最初的问题陈述不是很清楚

这是我的代码(对于n>6):

我知道这不是很有效,我一直在编辑它,试图找到错误


(C++)

整个问题归结为寻找六个元素中最伟大的元素,你已经尝试了
4+6/2=7
。对于六个以上的元素,每次尝试都会从中选出两个(这是您已经做过的),因此公式
4+N/2
就是从这里来的

前五项测试(实际上,我们所需要/能够做的就是):

现在我们可以确定3、4和5不可能是最重的,剩下的1、2和6

现在让我们仔细看看:

从集合中删除5或6将导致两次相同的第3次和第4次。 从集合结果中删除4将导致第三个和第四个组合只出现一次。 从集合中删除1、2或3会在相同的第3和第4个结果中出现三次

我们现在感兴趣的正是这两组,第3组和第4组正好出现两次:

1,2,3,4,5和1,2,3,4,6。从中我们知道5或6一定是最大的;再加上第一次观察(3、4、5次除外),只剩下6次

事实上,我们知道的更多:

从两个引用(5,6)中未选择的引用(5)为第二重引用,第三/第四个引用(4)中的单个引用显示为第三重引用,从最初排除的引用(3,4,5)中剩余的引用(3)为第四重引用

仅第五和第六无法区分

编辑:过滤剩余值:

您可以稍微简化代码:

int t;
std::cin >> t;
while(t--) // sparse you another variable...
{
    int n = 12;
    --n; // exclude highest value!
    int ar[] = {1, 2, 3, 4, 5}; // just *always* maintain the values in the array...
    // note: the array is one larger as you had initially!
    for (int i = 6; i < n; i = i + 2) // prefer local scope for i!
    //           ^ can start at a later point of time, we'll be replacing AFTERWARDS
    {
        std::cout << '?';
        for(auto a : ar)            // loop might or not be more elegant
            std::cout << '\t' << a; // performance: most likely, compiler unrolls
                                    // anyway...
        std::cout << std::endl;
        int x, y; // scope as local as possible...
        std::cin >> x >> y;
        // OK, I don't want to modify the loop variable, so I now use a duplicate...
        int ii = i;
        for(auto& a : ar) // I like the range based for loops...
        //      ^ reference this time is important, though!
        {
            if(a == x || a == y)
                a = ii++;
        }
    }
    if((n & 1) == 0)
    {
        // for even n, we have done one test too few!
        // instead of duplicating the code, you might write a common function for...
        std::cout << '?';
        for(auto a : ar)
            std::cout << '\t' << a;
        std::cout << std::endl;
        int x, y; // scope as local as possible...
        std::cin >> x >> y;

        for(auto& a : ar)
        {
            if(a == x || a == y)
            {
                a = n;
                break; // just replace one!!!
            }
        }
    }
}
n
现在将是要检查的第六个值,除了数组中剩余的五个值之外(如果您不喜欢递增和递减,当然也可以保留两个变量)。您可以使用
std::swap
一个接一个地交换数组的值

旁注:我个人更喜欢像C++的
std::array ar({1,2,3,4,5})而不是原始数组,但这不是什么大问题。但是,如果使用重复的代码创建一个数组,则可以更轻松地将数组传递给函数:

void f(std::array<int, 5> const& ar); // or non-const, if you want to replace inside, too
// or in more generic form:
template <size_t N>
void f(std::array<int, N> const& ar);

// vs.:

void f(int const(&ar)[5]);
// the more generic form:
template <size_t N>
void f(int const(&ar)[N]);
// or classical (and better known) pointer variant:
void f(int const* ar, size_t length);
void f(std::array const&ar);//或者非常量,如果你想替换内部
//或以更一般的形式:
样板
void f(std::数组常量和ar);
//vs:
无效f(整数常量和ar)[5];
//更通用的形式:
样板
无效f(整数常量和ar)[N];
//或经典(更广为人知)指针变体:
空隙f(整型常数*ar,尺寸长度);
最后的旁注:

  • 用户输入后不检查流。如果用户输入任何invlid,这将破坏您的流,从而破坏整个代码。在这种特定情况下可能不需要这样做,但一般来说,从一开始就习惯(比如
    if(!cin>>x>>y){/*适当的错误处理*/}
    ),甚至可以在之后检查有效范围(例如,错误,如果
    x
    y
    相等或与数组中的一个值不完全匹配——对于后者,我们必须注意与已替换的值不匹配)
  • 就我所理解的问题而言,负值是没有意义的,因此我(一贯)更喜欢
    unsigned int
    作为数据类型。但这不是什么大问题,所以请自行决定

  • 请注意,我确实理解您遇到的问题-您能否澄清您看到的确切错误是什么?您使用的是什么输入数据,预期的输出是什么,实际的输出是什么?@codeling这就是问题所在。Codechef不提供测试用例,我尝试制作了一些自己的测试用例,效果很好。然后请在t中明确说明问题-codechef报告您的代码不正确,而您使用x、y和z对其进行了测试,并提供了a、b和c的预期结果…
    fflush(stdout)
    (c)-->
    也只是进行刷新…我的代码对n6不起作用,在反复删除第三和第四大值后,我们知道数组中还有2个最轻和最重的元素。因此,通过检查这3个元素之间的4个随机权重,我们可以从输出中推断出2个测试中最重的元素。我们从数组中提取1个元素4个随机值,测试两次,如果输出不变,我们测试的2个数组元素必须是最小的2个,如果输出向左移动,