洛谷P1160队列安排从单链表到数组实现循环双链表-创新互联

题目描述

一个学校里老师要将班上 N 个同学排成一列,同学被编号为 1∼N,他采取如下的方法:

目前创新互联已为近千家的企业提供了网站建设、域名、虚拟主机成都网站托管、企业网站设计、大埔网站维护等服务,公司将坚持客户导向、应用为本的策略,正道将秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。
  1. 先将 1 号同学安排进队列,这时队列中只有他一个人;

  1. 2∼N 号同学依次入列,编号为 i 的同学入列方式为:老师指定编号为 i 的同学站在编号为 1∼(i−1) 中某位同学(即之前已经入列的同学)的左边或右边;

  1. 从队列中去掉 M 个同学,其他同学位置顺序不变。

在所有同学按照上述方法队列排列完毕后,老师想知道从左到右所有同学的编号。

输入格式

第一行一个整数 N,表示了有 N 个同学。

第 2∼N 行,第 i 行包含两个整数k,p,其中 k 为小于 i 的正整数,p 为 0 或者 1。若 p 为 0,则表示将 i 号同学插入到 k 号同学的左边,p 为 1 则表示插入到右边。

第 N+1 行为一个整数 M,表示去掉的同学数目。

接下来 M 行,每行一个正整数 x,表示将 x 号同学从队列中移去,如果 x 号同学已经不在队列中则忽略这一条指令。

输出格式

一行,包含最多 N 个空格隔开的整数,表示了队列从左到右所有同学的编号。

输入输出样例

输入 #1复制

4

1 0

2 1

1 0

2

3

3

输出 #1复制

2 4 1

说明/提示

【样例解释】

将同学 2 插入至同学 1 左边,此时队列为:

2 1

将同学 3 插入至同学 2 右边,此时队列为:

2 3 1

将同学 4 插入至同学 1 左边,此时队列为:

2 3 4 1

将同学 3 从队列中移出,此时队列为:

2 4 1

同学 3 已经不在队列中,忽略最后一条指令

最终队列:

2 4 1

【数据范围】

对于 20% 的数据,1≤N≤10。

对于40% 的数据,1≤N≤1000。

对于 100% 的数据,1

一开始用单链表写的,里面的查询次数直接爆了哎,这是我本来的代码,学单链表插入删除最后只能完成40%的数据(没办法人菜瘾大)

#includeusing namespace std;
typedef struct Lnode
{
item data=0;
struct Lnode* next=NULL;
}Lnode,*linknode;
bool InitLink(linknode& s)
{
s = new Lnode;
if (s == NULL)
{
return false;
}
return true;
}
int insertitem(linknode& s, int k, int p, item e) {
linknode newLnode = new Lnode;
if (newLnode == NULL) { cout<< "内存不足,分配失败"; return 0; }
newLnode->data = e;
linknode a = s->next;//遍历指针1
linknode b = s;//遍历指针2
while (a != NULL)
{
if (a->data == k)break;
b = b->next;
a = a->next;
}
//插入到左边
if (p==0)
{
b->next = newLnode;
newLnode->next = a;
return 1;
}
//插入到右边
newLnode->next = a->next;
a->next = newLnode;
return 1;
}
int t[100000 + 1] = {0};
int main()
{
linknode s = NULL;
if (InitLink(s) == false) { cout<< "内存不足,分配失败"; return 0; };
linknode newfirst = new Lnode;
newfirst->data = 1;
s->next = newfirst;
int n;
cin >>n;
for (item i = 2; i<= n; i++)
{
int k, p;
cin >>k >>p;//k号同学,p值不同插入的方向不同
if (insertitem(s, k, p, i) == 0) { return 0;}
}
int m;
cin >>m;
item x;
for (int i = 0; i< m; i++)
{
cin >>x;
if (t[x] == 1) { continue; }
t[x] = 1;
linknode p = s->next;
linknode z = s;
while (p)
{
if (p->data==x)
{
linknode l = p;
z->next = p->next;
free(l);
break;
}
p = p->next;
z = z->next;
}
}
while (s)
{
if (s->data != 0) {
cout<< s->data<<" ";
}
s = s->next;
}
return 0;
}

因为查找数据很慢,所以后面看别人的做法,只能惊叹太强了,因为输入输出都是整数且连续直接用结构体来代替双链表。太强了!!!然后我用数组实现循环双链表,重写这个题

#includeusing namespace std;
typedef struct stu
{
int l=0, r=0;
}students;
int main() {
int n;
cin >>n;
students  s[100000 + 5];
//构造两个结点的循环双链表
s[0].r = 1;
s[0].l = 1;
s[1].l = 0;
s[1].r = 0;
bool flag[100000 + 5] = { false };//默认不输出
flag[1] = true;//1默认输出
for (int i = 2; i<= n; i++)//增加
{
int k, p;
cin >>k >>p;
if (p == 0)//插入到左边
{
s[s[k].l].r = i;
s[i].l = s[k].l;
s[i].r = k;
s[k].l = i;
}
if (p == 1)//插入到右边
{
s[s[k].r].l = i;
s[i].r = s[k].r;
s[i].l = k;
s[k].r = i;
}
flag[i] = true;
}
int m;
cin >>m;
for (int i = 0 ; i< m ; i++)
{
int x;
cin >>x;
if (flag[x] == false)continue;
     //删除的操作,毕竟不是真实的空间不需要free
s[s[x].l].r = s[x].r;
s[s[x].r].l = s[x].l;
flag[x] = false;
}
int p = s[0].r;
for (p =s[0].r;p!=0;p=s[p].r)
{
cout<< p<< " ";
}
return 0;
}

最后感觉还是要发散思维,确实见识太少了

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧

网站栏目:洛谷P1160队列安排从单链表到数组实现循环双链表-创新互联
当前路径:https://www.cdcxhl.com/article0/csdeoo.html

成都网站建设公司_创新互联,为您提供网站维护网页设计公司定制开发软件开发营销型网站建设网站导航

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

成都做网站