#include <iostream>
using namespace std;
#include<stdlib.h>
#include<string.h>
#include<string>
int main(void)
{
int N;
cin >> N;//输入人数
//根据人数创建 left right IsOut 数组
int* left = (int*)malloc(sizeof(int) * (N + 1));
int* right = (int*)malloc(sizeof(int) * (N + 1));
bool* IsOut = (bool*)malloc(sizeof(bool) * (N + 1));
//初始化数组
//如果左没有人的话 其left 为-1;右边没有人的话1, 其 right 为-1
memset(left, -1, sizeof(int) * (N + 1));
memset(right, -1, sizeof(int) * (N + 1));
memset(IsOut, true, sizeof(bool) * (N + 1));//一开始都未去掉,设标志位为true
int index = 1;//这是记录左边第一个人的所对应的号码,一开始1号位于最左边 所以一开始index记录的是1
for (int i = 2; i <= N; i++)
{
int nums;//要被插入的号码
int flag;//标志左还是右 1为右 0为左
cin >> nums >> flag;
if (flag == 1)//右边
{
//1.当前标号的右边等于nums的右边
right[i] = right[nums];
//2.记得将nums的左边的右边变为当前标号
left[right[nums]]= i;
//3.再把nums的右边变为当前标号
right[nums] = i;
//4.最后把当前标号的left变为nums
left[i] = nums;
//右边插入完毕
}
else
{
//1.先把当前标号的左边变为nums的左边
left[i] = left[nums];
//2.再把nums左边的右边变为当前标号
right[left[nums]] = i;
//3.再把nums的左边变为当前标号
left[nums] = i;
//4.再把当前标号的右边变为nums
right[i] = nums;
//左边插入完毕
}
if (left[i] == -1)
{
index = i;//更新最左边的标号
}
}
int M;
cin >> M;//输入要去掉的人数
for (int i = 0; i < M; i++)
{
int number;
cin >> number;//输入号码
if (IsOut[number])//如果未被去掉过
{
IsOut[number] = false;//标记为去掉过
if (left[number] != -1)//如果number左边还有人
{
right[left[number]] = right[number];//就把它左边的右边变为它的右边
}
if (right[number] != -1)//如果number右边还有人
{
left[right[number]] = left[number];//就把它的右边的左边变为它的左边
if (left[right[number]] == -1)index = right[number];//更新最左边的号码
}
}
}
while (right[index] != -1)//循环,如果当前index的右边为-1,则说明他是最后一个人
{
cout << index << ' ';//输出当前的人
index = right[index];//把它的右边赋值给index,更新index
}
cout << index << ' ';//把最后一个人也输出
return 0;
}
洛谷:队列安排 1160 (c/c++题解思路分享)
最新推荐文章于 2023-12-05 11:06:35 发布