思路:使用一个栈来尝试复现结果
不断地将输入序列压栈,当栈顶元素等于待比较的第一个元素时,出栈,并开始比较下一个待比较元素,若出栈后的栈顶元素还是与下一个待比较元素相同时,继续出栈,以此类推…当栈顶元素不相同时,开始不断地压栈并将栈顶元素与待比较元素做比较,若当输入元素已用完或输入元素还剩余但是栈已经满了时,栈顶元素不等于待比较元素,则判断为“NO”;若正常的比较完了待比较元素,则判断为“YES”。
// 参考:https://blog.csdn.net/lisongjia123/article/details/49706363
#include <stdio.h>
#include <stdlib.h>
#pragma warning( disable : 4996 )
#define MAXSIZE 1000
struct Stack
{
int number[MAXSIZE];
int top;
};
typedef struct Stack* PtrS;
// 创建一个新栈,并初始化
PtrS CreateStack();
// 入栈
void Push(PtrS S,int number);
// 出栈
int Pop(PtrS S);
int main()
{
int M;// the maximum capacity of the stack
int N;// the length of push sequence
int K;// the number of pop sequences to be checked
scanf("%d %d %d", &M, &N, &K);
int SampleInput[MAXSIZE][MAXSIZE];
for (int i = 0; i < K; i++)
{
for (int j = 0; j < N; j++)
{
scanf("%d", &SampleInput[i][j]);
}
}
for (int i = 0; i < K; i++)// 共有K个待比较序列
{
PtrS MyStack = CreateStack();
int j = 0;// j在此循环中代表待验证序列的第j+1个元素
int InputElement = 1;// InputElement代表输入序列中将要入栈的元素
int NoFlag = 0;// 判断是否是正常退出本轮检验
while(j < N)
{
if (InputElement <= N)// 如果还有输入元素
{
if (MyStack->top < M - 1)// 栈不满就一直可以压
{
Push(MyStack, InputElement);// 相当于将1~N按顺序压入栈中
InputElement++;// 每次输入元素的值加1
}
if (MyStack->top == M - 1 && MyStack->number[MyStack->top] != SampleInput[i][j])// 如果栈已经满了
{
printf("NO\n");
NoFlag = 1;
break;
}
}
else// 当输入元素用完
{
if (MyStack->number[MyStack->top] != SampleInput[i][j])// 且栈顶元素不等于待比较元素时
{
printf("NO\n");
NoFlag = 1;
break;
}
}
while(MyStack->number[MyStack->top] == SampleInput[i][j])// 若栈顶元素等于待比较的元素,一直出栈
{
Pop(MyStack);
j++;// 开始比较下一个待验证的元素
if (MyStack->top == -1)
break;
}
}
if (NoFlag == 0)
printf("YES\n");
}
}
PtrS CreateStack()
{
PtrS NewStack = (PtrS)malloc(sizeof(struct Stack));
NewStack->top = -1;
return NewStack;
}
void Push(PtrS S, int number)
{
if (S->top == MAXSIZE)
return;
else
{
S->top += 1;
S->number[S->top] = number;
}
}
int Pop(PtrS S)
{
if (S->top == -1)
return -1;// 栈满返回-1
else
{
S->top = S->top - 1;
return S->number[S->top + 1];// 要先减再return,不然就减不到了
}
}
结果截图: