C++ 最大元素的打印索引
彼得有N个球,编号从1到N 没有两个球的重量相同。你想找到最重的球,但你不知道它是哪一个,彼得也不想把它给你。因此,他决定和你玩一个游戏 你最多可以问彼得Q=4+N/2个问题。在每个问题中,你必须给彼得五个不同球的编号,彼得告诉你这些球中第三和第四重球的编号。找到最重的球的数目 互动: 首先,您应该读取一行,其中包含一个表示测试用例数量的整数T。 对于每个测试用例,您应该从读取包含单个整数N的行开始。 要提问,您应该打印一行,其中包含字符“?”、一个空格和五个空格分隔的整数i1、i2、i3、i4和i5:五个不同球的数目(按任意顺序) 然后,您必须读取一行包含两个空格分隔的整数:第三和第四重球的编号 要完成测试用例的求解,请打印一行包含字符“!”,一个空格和一个整数im:最重的球的数目(1≤感应电动机≤N) 打印每行后,不要忘记刷新输出 约束条件:C++ 最大元素的打印索引,c++,algorithm,logic,interactive,C++,Algorithm,Logic,Interactive,彼得有N个球,编号从1到N 没有两个球的重量相同。你想找到最重的球,但你不知道它是哪一个,彼得也不想把它给你。因此,他决定和你玩一个游戏 你最多可以问彼得Q=4+N/2个问题。在每个问题中,你必须给彼得五个不同球的编号,彼得告诉你这些球中第三和第四重球的编号。找到最重的球的数目 互动: 首先,您应该读取一行,其中包含一个表示测试用例数量的整数T。 对于每个测试用例,您应该从读取包含单个整数N的行开始。 要提问,您应该打印一行,其中包含字符“?”、一个空格和五个空格分隔的整数i1、i2、i3、i4
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个,如果输出向左移动,