问题:一家公司招聘候选人,让他们坐成一圈。 他们选择每一个候选人并离开圆圈(因此圆圈越来越小),直到只留下一个。 所以,如果有5个人,那就像: -
1 2 3 4 5
1 3 4 5 (2 is selected)
1 3 5 (4 is selected)
3 5 (1 is selected)
3 (3 is left, does'nt get the job!)
Jhon是一个超级帅哥,不想成为这个恶意公司的一部分。
如果他知道共有560人,他会站在哪里。 Ans:我试图制作一个你输入n的程序(候选人数) 并且它将打印一个未被选中的座位的值。
我使用了循环链表和删除。
请耐心等待我,因为我对编码很新。
我的程序适用于输入2,4,8,16,32,64等,因为所有这些都是1。 但任何其他输入,它都无法正常工作。
#include <iostream>
using namespace std;
struct node
{
node* ptr;
int data;
}start;
int main()
{
node *start=NULL;
int n;
cout<<"Enter the number of students : ";
cin>>n;
node *temp=new node;
temp->data=1;
temp->ptr=NULL;
start=temp;
for(int x=2;x<=n;x++)
{
node* temp1=new node;
temp1->data=x;
temp->ptr=temp1;
temp1->ptr=start;
temp=temp1;
}
node* temp2=start;
do
{
cout<<temp2->data<<" ";
temp2=temp2->ptr;
}while(temp2!=start);
cout<<endl;
//delete bigins here
temp2=start;
node* temp3=temp2->ptr;
do
{
temp2->ptr=temp3->ptr;
temp3->ptr=NULL;
delete temp3;
temp2=temp2->ptr;
temp3=temp2->ptr;
}while(temp2->ptr!=start);
temp2=start;
do
{
cout<<temp2->data<<" ";
temp2=temp2->ptr;
}while(temp2!=temp3);
cout<<endl;
}
答案 0 :(得分:2)
我的程序适用于输入2,4,8,16,32,64等,因为所有这些都是1。
这是一个很好的观察。实际上,答案距离这里只是一小步。
您有n
个候选人,每次选择1个。如果n
为x + 2^k
(最大可能为k),则在x
步后,您会留下2^k
个候选人,并且该行中的下一位候选人就是答案。所以答案是2x+1
。
1 2 3 4 5 6 7
^ ^ ^ |
removed |
answer
注意:此练习可在Concrete Mathematics: Foundation for Computer Science中找到。我强烈推荐它。
答案 1 :(得分:2)
问题在于核心循环:
do {
temp2->ptr=temp3->ptr;
temp3->ptr=NULL;
delete temp3;
temp2=temp2->ptr;
temp3=temp2->ptr;
} while (temp2->ptr!=start);
此循环仅对数据进行一次:它在第一组删除结束时停止,因为它在第一次返回start
时停止。这就是为什么你总能得到答案1,正如你所指出的那样,当列表长度是2的幂时,这是正确的。
相反,它应该循环,直到只剩下一个node
,这将指向自己作为下一个node
。所以do ... while
循环的最后一行应该是:
} while (temp2->ptr != temp2)
显然世界已经开始了:我第一次听到这个谜题是关于海盗喝毒药以确定谁得到了宝藏!
答案 2 :(得分:0)
大大简化您的解决方案,实施“软删除”。在你的节点结构上放一个名为“int deleted”的标志,并将其初始化为0.每次要删除一个节点时,只需设置deleted = 1.你的问题中的指针逻辑有问题,这就解决了大部分问题
当您正在寻找要删除的下一个节点时,如果节点已删除== 1,则不要将其计为其余节点之一,只需继续操作,直到找到第二个节点已删除= 0 ,并将其设置为1。
您甚至不需要循环列表,甚至此时也不需要列表。您可以使用值为0或1的整数数组。如果您仍然计算剩余数量,那么只要剩下一个,就可以停止,否则您将不得不遍历整个数组确保没有剩下的。
这不是那么快,因为你的列表永远不会变小,而且你正在查看大量已删除的条目,但它更简单。
答案 3 :(得分:0)
第二次执行while循环(删除)时出现一个小错误。 while语句在迭代一次之后强制循环终止,即,一旦它到达起始节点,它就退出。您需要更改行
while(temp2->ptr!=start);
到
while(temp2->ptr!=temp2);
最后一次while循环似乎遇到了无限循环,因为它上面的语句:
temp2 = start;
删除期间,您不会跟踪删除元素1后立即删除的开始指针。因此temp2指向垃圾。删除此行也应该解决这个问题。