/* 顺序栈表示:函数定义 */
/* 顺序栈表示:类型和界面函数声明 */
enum { MAXNUM = 20 /* 栈中最大元素个数,应根据需要定义 */
};
typedef int DataType; /* 栈中元素类型,应根据需要定义 */
struct SeqStack { /* 顺序栈类型定义 */
int t; /* 栈顶位置指示 */
DataType s[MAXNUM];
};
typedef struct SeqStack *PSeqStack; /* 顺序栈类型的指针类型 */
/*创建一个空栈;为栈结构申请空间,并将栈顶变量赋值为-1*/
PSeqStack createEmptyStack_seq( void ) {
PSeqStack pastack = (PSeqStack)malloc(sizeof(struct SeqStack));
if (pastack==NULL)
printf("Out of space!! \n");
else
pastack->t = -1;
return pastack;
}
/*判断pastack所指的栈是否为空栈,当pastack所指的栈为空栈时,则返回1,否则返回0*/
int isEmptyStack_seq( PSeqStack pastack ) {
return pastack->t == -1;
}
/* 在栈中压入一元素x */
void push_seq( PSeqStack pastack, DataType x ) {
if( pastack->t >= MAXNUM - 1 )
printf( "Stack Overflow! \n" );
else {
pastack->t++;
pastack->s[pastack->t] = x;
}
}
/* 栈顶元素出栈,x存储数据 */
void pop_seq( PSeqStack pastack, DataType *x ) {
if (pastack->t == -1 )
printf( "Underflow!\n" );
else
{
*x=pastack->s[pastack->t];
pastack->t--;
}
}
/*只出栈,不返回元素*/
void dele_seq( PSeqStack pastack ) {
if (pastack->t == -1 )
printf( "Underflow!\n" );
else
pastack->t--;
}
/* 当pastack所指的栈不为空栈时,求栈顶元素的值 */
DataType top_seq( PSeqStack pastack ) {
return pastack->s[pastack->t];
}
#include"stack.h"
bool isMax(int* arr, int pos,int Len) //判断下标为pos的数字是否比它之后的数字都要大
{
int max=arr[pos];
for(int i=pos+1; i<Len; i++)
{
if(max<arr[i]) max=arr[i];
}
if(max==arr[pos])
return true;
else return false;
}
bool isincrease(int *arr,int pos,int Len) //判断下标为pos的数字之后的数字是否递增
{
int min=arr[pos];
for(int i=pos+1; i<Len; i++)
{
if(min<arr[i]) min=arr[i];
else
return false;
}
if(i==Len)
return true;
}
int isCanJudge(int* arr, int Len) //主函数
{
PSeqStack pastack;
pastack = createEmptyStack_seq();
int i; //入栈的数字
int j; //arr的下标
for(j=0; j<Len; j++)
{
i=1;
do
{
push_seq( pastack, i );
if(i==arr[j])
{
dele_seq( pastack );
if(j<Len-2 && isMax(arr, j, Len)==true && isincrease(arr,j+1, Len)==true)
{
printf("NO\n");
return 0;
}
while(isEmptyStack_seq( pastack )!=1)
{
j++;
if(arr[j]==top_seq( pastack ))
dele_seq( pastack );
if(j<Len-2 && isMax(arr, j, Len)==true && isincrease(arr,j+1, Len)==true) //54123
{
printf("NO\n");
return 0;
}
else break;
}
}
i++;
}while(i<=Len);
}
if(j==Len || j==Len+1)
{
printf("YES\n");
return 1;
}
}
#include<stdio.h>
#include"stdlib.h"
#include"function.h"
void main()
{
int *arr;
int Len;
int c;
scanf("%d",&Len); //输入数组的长度
while(1)
{
if(Len==0) exit(1);
else
{
arr=(int *)malloc(sizeof(int)*Len);
while(1)
{
for(int i=0; i<Len; i++)
{
scanf("%d",&arr[i]); //输入测试数组
if(arr[0]==0)
{
printf("\n");
break;
}
}
if(arr[0]!=0)
isCanJudge(arr,Len); //结果
else break;
}
scanf("%d",&Len);
if(Len==0) exit(1);
}
}
}
题源:POJ1363(Rails)
写这个题目真的要比HDU1237艰难……这次完完全全是自己从0开始想开始写的(栈的基操的头文件是老师给的,但我觉得这是高效搬砖,这种基础的轮子不必自己重造)。
做这个题刚开始难在看不懂题目(题源全英),尝试了百度翻译还是不太明白。查看这个链接后明白了题意:按照1…n的顺序输入 能否输出你输入的那种序列
反思总结:
1.先说一个无关这个题目的反省…之前在贴代码块的时候不知道可以选语言类型,导致之前的文章代码都是白色的。现在发现选了语言之后代码更清晰可观,之后还是写博客还是要记得这个细节。
2.用了我写HDU1237的方法,先用“123”三个数字作为例子,把所有排列顺序找出并判断是否能按该顺序出栈。例子成功后再用题目中5位数和6位数的情况运行代码,判断正确就当作成功了。之后自己也写了一个4位数的例子用作判断,也没问题。
3.在写isCanJudge(int* arr, int Len) 这个主函数的时候,刚开始返回值设为 void,之后发现需要运行多个例子时,函数会被重复调用。函数当中如果用 exit(1) 来退出函数,整个程序都会结束。把函数返回值设为int,用return来退出当前函数 即可解决 需要重复调用函数 问题。
4.把这片代码提交到oj系统运行了整整2min…最后还是submit false。老师之前说这个提交好像有问题,但是我的这个方法应该是很耗时,我参考了别人的代码都是比较短的我也不太能看明白。代码水平确实不足。
5.这个题目设计到的变量基本都是存储数字,有的是下标,有的些是入栈的数值,有的是数组里面的待测数值……数字太多的情况下不仅要用到调试来观察变量的数值变化,最好开一个word文档来记录哪一个下标对应哪一个数值做什么事情。
6.这个实现方法用到很多 if 语句,在写 if 语句的判断条件时要留意当前有什么变量可以用来进行判断。在判断条件比较复杂时,可以另外写一个函数(如题中的 isMax(int arr, int pos,int Len)* 函数和 isincrease(int arr,int pos,int Len) 函数)来辅助判断。