洛谷:队列安排 1160 (c/c++题解思路分享)

#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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值