SJTU火车调度(OJ1049)

题目源自SJTU OJ1049

有一条东西方向的铁路穿过小城A,小城A有一个火车调度站,示意图如下:

火车调度

现在有N列火车自东向西依次开过来了,按照到达的先后次序编号为0号到N-1号。 根据调度局的要求,小城A的调度站要改变这些列车驶离A城的顺序。 为了达到这一目的, 调度站在任意时刻可以执行以下三种操作之一:

如果调度站还有剩余空间,则可以令下一列开来的火车进入调度站;

如果调度站内有列车,则可以令调度站最前方的火车离开调度站并驶离A城;

可以命令下一列开来的火车不经过调度站而直接驶离A城。

不过小城A的调度站实在太小了,只能容纳M列火车,请帮忙确认调度站能否完成任务。

例子
如果有4列火车开来,调度站可以容纳2列火车,调度局要求火车按照2、1、3、0的顺序驶离A城,则此任务可满足,一种可能的方案如下:

Step 1:火车0进入调度站;

Step 2:火车1进入调度站;

Step 3:火车2不经过调度站驶离A城;

Step 4:火车1从调度站驶离A城;

Step 5:火车3不经过调度站驶离A城;

Step 6:火车0从调度站驶离A城;

当然,你只需要回答是否可行,不需要列出一种可行方案。

Input Format
第一行是一个正整数
T
,表示本测试数据有多少个独立的测试点。(
T

300

之后有
T
个独立的测试点,每个测试点占两行。 第一行有两个数字
N

M
,分别表示开来的火车数量,以及调度站最多可容纳的火车数量,两个数字之间用一个空格隔开。 第二行有
N
个整数,他们都在
0

N

1
之间,且不重复,用空格隔开,表示火车驶离A城的次序。

N
是正整数,且
N

1000

M
是非负整数,且
M

1000

M
可能为
0
(这也许说明调度站的工作人员罢工了,或者正在这个考场考试)。

Output Format
输出共
T
行,每行对应一个测试点。如果能够调度,则回答YES,否则回答NO。 输出请注意大小写,每行行末直接回车,不要有其他字符。

Sample Input
2
4 2
2 1 3 0
5 2
2 4 3 1 0
Sample Output
YES
NO

#include<iostream>

using namespace std;

bool check()
{
	int N, M;
	cin >> N >> M;
	//    if (M == 0) return false;
	int* stack = new int[M];
	int* queue = new int[N];
	//    int stack[2] = {0};
	//    int queue[5] = {2, 4, 3, 1, 0};
	for (int i = 0; i < N; ++i) {
		cin >> queue[i];
	}
	int j = 0, top_p = 0;
	for (int i = 0; i < N; ++i) {
		if (i != queue[j]) {
			if (top_p > M - 1) {
				delete[]queue;
				delete[]stack;
				return false;
			}
			stack[top_p] = i;
			top_p++;
		}
		else {
			j++;
			while (top_p > 0) {
				if (stack[top_p - 1] == queue[j]) {
					top_p--; j++;
					continue;
				}
				else {
					break;
				}
			}
		}
	}
	while (top_p > 0) {
		if (stack[top_p - 1] == queue[j]) {
			top_p--; j++;
			continue;
		}
		else {
			delete[]queue;
			delete[]stack;
			return false;
		}
	}
	delete[]queue;
	delete[]stack;
	return true;
}

int main()
{
	int T;
	cin >> T;
	for (int i = 0; i < T; ++i) {
		if (check())
			cout << "YES" << endl;
		else
			cout << "NO" << endl;
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值