洛谷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队列安排从单链表到数组实现循环双链表-创新互联
链接URL:http://scyanting.com/article/csdeoo.html