如何解决合并递归树中相同级别的节点
我了解解决此问题的方法。
问题A。它是同质的吗?
Alex具有大小为N(1≤N≤1000)的1个索引秘密数组A。
您必须猜测A中的所有元素是否都是成对互质的, 就是所有1≤i
gcd(Ai,Aj)= 1。
您最多可以问亚历克斯(Alex)15个问题 {1,2,3,... N}的两个不相交的子集,例如S1和S2,Alex将 计算P1 = ∏ Ai,P2 = ∏ Ai并告诉您(i∈S1i∈S2)gcd(P1, P2)= 1。
为方便起见,Alex将空集的乘积定义为1。
有趣的是,找不到Alex了,取而代之的是我们在这里为您解决此问题的方法。
输入
单个整数N,即数组A的大小,位于 相互作用。请参阅“交互的交互协议”部分 协议。
输出
为清晰起见,请从“交互”进行复制。每个查询的格式为Q I1 I2 I3。 。 。 In(以空格分隔的整数),其中Ij∈{0,1,2}。的 最终答案的格式为“互质数”或“否”。 (阅读互动 协议部分进行说明)
交互协议
对于每个查询,请打印一行格式为Q I1 I2 I3的行。 。 。在太空 分隔的整数),其中Ij∈{0,1,2}至stdout。 •Ifj∈S1,Ij 应该是1。 •如果j∈S2,则Ij应该为2。 •如果jisnotinS1或S2,则Ij应该为0。 然后,从stdin读取一个整数,如果gcd(P1,P2)= 1,则为1。 否则为0。知道答案后,如果显示“ A coprime” 认为A是成对的互质,否则打印“ A no”(不带引号)。
请注意,您不必询问15个问题,您可以打印答案 一知道,然后退出。
此外,在打印完每个查询甚至答案后,您必须执行 在标准输出上冲洗。您可以在C ++中使用fflush(stdout)和google查找 在其他语言中有效的方法。
但是我在实现算法和解决问题时遇到了麻烦。
我的工作:将秘密阵列分为两个较小的阵列,分别形成S1和S2。如果在线判断器的输出为1,则继续将每个较小的数组像较大的数组一样划分。这一直持续到我们得到一个单独占用的数组为止。如果判断输出在任何时候为0,则整个程序终止并输出:“ A否”。这是O(N),我为此编写了以下代码:
#include<iostream>
using namespace std;
bool ask(int n,int start,int end)
{
if (end-start == 0)
return true;
int middle = (start+end)/2;
cout<<"Q"<<" ";
for (int i=1;i<=start-1;i++)
cout<<0<<" ";
for (int i=start;i<=middle;i++)
cout<<1<<" ";
for (int i=middle+1;i<=end;i++)
cout<<2<<" ";
for (int i=end+1;i<=n;i++)
cout<<0<<" ";
cout<<endl;
int answer;
cin>>answer;
if (answer == 1)
return (ask(n,start,middle) and ask(n,middle+1,end));
else
return false;
}
int main()
{
int n;
cin>>n;
if (ask(n,1,n) == true)
cout<<"A coprime"<<endl;
else
cout<<"A no"<<endl;
return 0;
}
但是,这显然需要进一步优化,并且可以通过将所有第n个层节点的第一个数组作为S1并相应地将第二个数组作为S2来组合第n个层节点(代表阵列的第n级分解)来实现。这具有时间复杂度O(logN),并且应该可以工作。
但是我在实现它时遇到了问题,因为它要求计算机记住所有的第n级节点并将它们组合在一起,因此很难像我那样递归地解决。
请注意:这出现在CodeForces上的2016 Exun Prelims中,我这样做只是出于学习的目的。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。