XDOJ-267 判断栈输出顺序正确与否

本题算是比较难的,如果要遍历每一个输出进行比较的话将会十分困难,但是通过逆向,我们将可以化难为易。基本思路是:将输入的出栈序列按照顺序进行弹出,如果能够弹出就证明输出正确,否则就输出错误。如按照此顺序弹出:3 2 1 7 5 6 4,那么就是先入栈123,之后进行比较将3出栈,再比较,将2、1分别出栈,再入栈4 5 6 7,再进行比较,出栈7,最后发现无法在不出栈6的情况下出栈5,则证明此顺序错误。但是,在这之中亦需要考虑栈是否已满,能否入栈等问题,因为此问题中栈的容量也是不确定的因素。

问题描述

给定一个栈,其中最多存储M个数据。将N个数据以1,2,3,...,N的顺序压栈,然后再随机弹栈。判断一下哪些是有可能的弹栈顺序,而哪些不是。例如M是5,N是7,我们可以得到1, 2, 3, 4, 5, 6, 7的弹栈顺序,而不能得到3, 2, 1, 7, 5, 6, 4这样的弹栈顺序。(M,N<=1000)

输入说明

输入包含了一种情况下的测试数据。在每种情况下,有三组输入数据:

第一组列在首行,包含了三个数据:栈的最大容量M,压栈数据长度N,要验证的弹栈序列个数K。

第二组为压栈数据:N个整数s1, s2, …, sn (1 ≤ si ≤ 10000, 1 ≤ i ≤ n)。

第三组为K行数据,每行包括了一个需要验证的弹栈序列(含N个数据)。

同行数据间以空格隔开。

输出说明

输出应该包括K行,包行了对每个输入的验证序列,输出的一个判断结果。如果这个弹出序列可能发生,就输出“YES”,否则就输出“NO”。

输入样例

5 7 5

1 2 3 4 5 6 7

1 2 3 4 5 6 7

3 2 1 7 5 6 4

7 6 5 4 3 2 1

5 6 4 3 7 2 1

1 7 6 5 4 3 2

输出样例

YES

NO

NO

YES

NO

#include<iostream>
#include<string>
#include<queue>
#include<stack>
using namespace std;
int main()
{
	int m,n,times, tempKey,keyi,tempNum;
	keyi = 0;
	
	int key[1005] = {};
	cin >>m>> n>>times;
	stack<int> s;
	queue<int> q;
	for (int i = 0; i < n; i++)
	{
		cin >> key[i];
	}
	for (int ii = 0; ii < times; ii++)
	{
		int Numi = 0;
		int Num[1005] = {};
		for (int i = 0; i < n; i++) //Num[]为待测试的数组
			cin >> Num[i];
		tempKey = key[keyi];
		s.push(tempKey);
		keyi++;
		for (;keyi < n; ) 
		{
			while (s.empty() || s.top() != Num[Numi])
			{
				s.push(key[keyi]);
				keyi++;
			}
			if (s.size() > m)
				break;
			while (!s.empty() && s.top() == Num[Numi])
			{
				s.pop();
				Numi++;
			}
		}
		if (s.empty())
			cout << "YES" << endl;
		else
			cout << "NO" << endl;
		while (!s.empty())
		{
			s.pop();
		}
		keyi = 0;
	}
	
	return 0;
}

欢迎大家关注:https://github.com/XDUgaile

写完的一些东西会不定时丢上去。

C语言中,如果你想将一个数字按照每一位的顺序输出(比如十进制转为字符形式),你可以使用`itoa()`函数或者自定义循环实现。`itoa()`函数通常不在标准库中提供,但在一些特定环境下可能会存在,如某些系统提供了`stdlib.h`头文件下的这个函数。 如果你需要一个通用的方法,可以创建一个自定义的函数,例如: ```c #include <stdio.h> #include <string.h> // 自定义版本的itoa,这里假设我们已经有了处理负数的逻辑 char* digit_output(int num, char buffer[]) { int sign = (num < 0) ? -1 : 1; num *= sign; // 确保非负数 if (num == 0) { buffer[0] = '0'; return buffer; } int i = 0; while (num > 0) { buffer[i++] = num % 10 + '0'; // 把每位转换成字符并添加到字符串前 num /= 10; } // 如果原数是负数,在前面加上负号 if (sign < 0) buffer[i++] = '-'; buffer[i] = '\0'; // 结束字符串 reverse(buffer); // 反转字符串以得到正确顺序 return buffer; } void reverse(char* str) { int start = 0, end = strlen(str) - 1; while (start < end) { char temp = str[start]; str[start] = str[end]; str[end] = temp; start++; end--; } } int main() { int number = 12345; char result[20]; strcpy(result, digit_output(number, result)); printf("Number in digits: %s\n", result); return 0; } ``` 在这个例子中,`digit_output`函数会把整数转换成字符数组的形式,并且`reverse`函数用于反转字符串,以便得到正常的数字顺序
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值