1.第三题---队列安排
下面的这个就是我们的题目:
题目描述:
1)4表示的就是哦们的这个队列里面是存在着4个元素的,但是这个1确定位置了,所以这个输入的就是三组,10表示的就是1号小朋友左边插入数据2(这个2就是默认的),也就是成了21
2)21表示的就是2号小朋友的右边插入这个数据3(3也是默认的),因此就是成为了231;
3)10表示的还是在我们的1号小朋友左边插入数据4(4也是默认的),因此就是2341的顺序结果;
4)2表示的就是我们接下来会进行两次的这个删除的操作;
5)3表示删除这个链表里面的3,因此就是241;
6)接下来的这个3表示的继续删除,但是因为经过上面的那个操作之后,这个链表没有3了,这个就结束了,直接输出此时我们的链表里面的节点即可;
下面的这个就是我们的代码:
1)p==1或者是p=1表示的就是我们的这个插入是左边插入,还是右边插入的;
2)p=0和p=1分别对应4行代码,这个就是我们的双向链表里面的指针的指向的修改,我在这个代码的后面有这个详细的图示,大家可以去看一下这个指向的变换的顺序;
3)m--里面的循环内容就是删除数据,删除的话,就是前面的指针直接指向下下个元素即可,两个指针的指向变一下,确认我们的元素是不是存在的,只有存在,也就是bool数值是false的时候才可进行这个删除的操作,删除之后这个置为true即可;
#include<iostream>
using namespace std;
const int N = 1e5 + 10;
int h, pre[N], ne[N];
bool st[N];//最后的时候判断我们的这个人是不是已经出去了,如果是已经出去的话,这个时候我们就不需要进行删除
int main()
{
int n; cin >> n;
pre[1] = h;
ne[h] = 1;//这个代码和上一行的代码就是完成的这个初始化的过程
for (int i = 2; i <= n; i++)
{
int k, p;
cin >> k >> p;
if (p == 0)
{
ne[i] = k;
pre[i] = pre[k];
ne[pre[k]] = i;
pre[k] = i;
}
else
{
pre[i] = k;
ne[i] = ne[k];
pre[ne[k]] = i;
ne[k] = 1;
}
}
int m; cin >> m;
while (m--)
{
int x;
cin >> x;
if (st[x]) continue;
ne[pre[x]] = ne[x];
pre[ne[x]] = pre[x];
st[x] = true;
}
for (int i = ne[h]; i; i = ne[i])
{
cout << i << " ";
}
return 0;
}
这个题目里面涉及到了我们的这个双向链表里面的这个数据的额插入和删除的相关的操作:下面我画图说明一下这个插入的顺序,因为这个是双向的链表,因此这个顺序可能就会稍微复杂一些啦;
下面的这个1234就是顺序理论上面而言,这个12是可以进行这个顺序的颠倒的,但是这34不可以进行这个顺序的变动,我们的这个12处理的都是我们的插入节点指向链表里面的节点的过程,这个34处理的都是我们的这个链表节点指向我们的这个插入的节点的过程,下面的这个是在k的左边进行这个数据的插入,因此这个现需要让我们的k左边的元素指向我们的这个插入的元素,然后让这个k指向我们的插入元素,如果这个顺序发生变化,也就是让这个k指向我们的插入元素,这个时候k前面的这个元素你是找不到的;
下面的这个右边进行插入的过程,也是类似,但是这个节点指向我们的插入数据的顺序发生了变化,具体的插入顺序如下图所示;这个时候是右边进行插入,因此这个34部发生了变化,大家结合下面的这个图进行类似理解即可
2第四题--约瑟夫环的问题
下面的这个事题目:
下面的这个是我们的这个约瑟夫问题的代码:
1)创建环形链表,最后一个链表指向我们的头结点即可;
2)模拟这个出圈的流程,这个时候我们不会数到3,而是数到2,直接删除这个数到2之后的数据即可,如果我们数到3,这个时候需要修改这个指针的指向,也就是需要删除的数据前面的元素指向需要删除的数据的后面的元素
3)但是这个时候你数到3,前面的元素已经找不到了,这个时候退回去了,这个是单向的;
4)因此数到2,直接删除下一个节点即可,这个也就是我们的j从1到小于m的原因,t就是我们的这个指针的指向,ne[t]就是需要删除的元素,然后修改指针的指向即可(ne[t]==ne[ne[t]]);
#include<iostream>
using namespace std;
const int N = 110;
int n, m;
int ne[N];
int main()
{
cin >> n >> m;
//创建我们的这个循环链表
for (int i = 1; i <= n; i++)
{
ne[i] = i + 1;
ne[n] = 1;
}
//模拟约瑟夫环形链表的流程
int t = n;
for (int i = 1; i <= n; i++)//执行n次的出圈的操作
{
for (int j = 1; j < m; j++)
{
t = ne[t];
}
cout << ne[t];
ne[t] = ne[ne[t]];
}
return 0;
}