POJ1363

/* 顺序栈表示:函数定义 */


/* 顺序栈表示:类型和界面函数声明 */

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) 函数)来辅助判断。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值