1051 Pop Sequence (25分)用状态转移方程来解,附多组测试样例及生成测试样例的代码
前言
题目不再赘述。目前本题大部分用的是stack模拟出栈的合法性。本文用状态转移方程做了一波,并给出多组测试用例,以及可以用来生成测试样例的代码。
例如不合法序列:1 2 3 4 7 5 6
目前考察元素5的出栈情况。
对于每个将要出栈的元素(5)而言,应当满足:该元素左边的元素(1,2,3,4)可以部分已经出栈,但是剩余元素的个数不得大于栈的深度5。
该元素右边的各个元素(6,7)要么全部都没有出栈,要么全部都已经出栈,再要么最右侧的所有都没出栈,紧邻5的元素们全部都已经出栈。
我们假设尚未进行出栈操作表示为1,已经进行出栈操作表示为0。那么将要出栈的元素右边的元素。合法的状态是:
- 11111111111…全部都没有出栈(出栈序列比当前元素靠后)。比如将要出栈5,那么序列5,(6,7,8,9)可能是一个合法解。
- 000000000…全部都已经出过栈(出栈序列比当前元素靠前)。比如将要出栈5,那么序列(6,7,8,9),5可能是一个合法解。
- 00000…111…最右边的都没出栈,最左边的都已经出过栈。比如将要出栈5,那么序列(6,7),5,(8,9)可能是一个合法序列。
不合法的状态是: - 00000…111111…0000。也就是说(6,7),(11,12),5,(8,9,10)这是一个不合法序列。
- 11111…0000…。即(8,9,10),5,(6,7)这是一个不合法序列。
状态0:000…,加0转至状态0,加1转至状态1。
状态1:000…111…,加0转至状态2,加1转至状态1.
状态2:000…111…000…已经非法,不管加0加1都是非法状态。可以与状态4合并。为了简便理解,这里不做合并。加0加1转至状态2。
状态3:111…,加0转至状态4,加1转至状态3.
状态4:111…000…,状态已经非法,不管加0加1都是非法状态,全部转移至状态4。
int stateTransfer[5][2] = {
{
0,1},{
2,1},{
2,2},{
4,3},{
4,4}};
//
//省略部分代码
//
int state;
if (check[t + 1] == -1)state = 3;
else state = 0;
for (int s = t + 2; s <= n; s++) {
state = stateTransfer[state][check[s]==-1];
}
if (state==2 || state == 4) {
flag = 0;
continue;
}
else {
check[t] = 0;
}
1.AC代码如下
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <cstring>
int check[1010];
int appear[1010];
int stateTransfer[5][2] = {
{
0,1},{
2,1},{
4,4},{
4,3},{
4,4} };
int main()
{
int m, n, k, t;
scanf("%d%d%d", &m, &n, &k);
for (int i = 0; i < k; i++) {
int flag = 1;
memset(check+1, -1, 4*n);
memset(appear + 1, 0, 4 * n);
for (int j = 0; j < n; j++) {
scanf("%d", &t);
if (!flag)continue;
if (appear[t]) {
flag = 0;
continue;
}
else {
appear[t] = 1;

本文用状态转移方程判断出栈合法性,区别于大部分用stack模拟的方法。阐述了将要出栈元素左右元素的出栈状态要求,给出合法与不合法状态示例,还提供了AC代码、生成测试数据的代码以及大量非法出栈队列测试用例。
最低0.47元/天 解锁文章
8684

被折叠的 条评论
为什么被折叠?



