题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=1022
这个题是数据类型--栈的实际应用,思路如下:
对栈和数组in[],out[]的处理:
三种情况:(把出站序列中的元素和栈中的元素进行比较,而不是和进站序列比较
//如果栈为空则处理第一个数据(并且要保证能退出循环)
//如果栈不空并且不等于当前出站序列中的数字,则必须再将后面的标号入栈
//如果栈不为空,并且栈顶元素等于当前出站序列中的当前位置,则出栈,并让出站序列向后,开始处理下一个出站序列
最后判断:
//若栈不为空,说明有列车滞留在车站中,肯定不能实现题目给出的出站序列
然后输入格式用print[]数组记录进出站的顺序,进站是1,出站是0,最后按顺序打印
自己写的代码:
#include<stdlib.h>
#include<stdio.h>
#define MAX 20
struct stack{
int st[MAX+1];
int top; //头部的指针
};
int Get_Top(stack); //取栈顶元素观看
void Pop(stack&);
void Push(stack&,int);
int is_Empty(stack);
void input(int*,int*); //读入火车进栈消息
int main()
{
stack S; //定义栈
int num;
int t;
int print[MAX*2+3]; //打印进栈顺序,1表示进栈,0表示出栈
int in[MAX+1];
int out[MAX+1]; //存储输入的火车进出顺序
while(scanf("%d",&num)!=EOF)
{
for(t=1;t<=MAX+1;t++) //对进栈数组初始化
{
in[t]=0;
}
S.top=1; //对栈初始化 ,每次都要初始化
int i=1,j=1,k=1,flag=0;
getchar();
input(in,out);
for(i=1;i<=num+1;)
{
if(is_Empty(S))
{
if(in[i]==0) //这边真的很难想,由于是整形数组,超过num时仍然有数,再被压入栈中 ,导致下面的循环又要进行一次错误
{ //如果全部处理完了,保证循环能退出来
i++;
}
else
{
Push(S,in[i]); //如果栈为空则处理第一个数据
i++;
print[k++]=1;
}
}
if(!is_Empty(S)&&Get_Top(S)!=out[j])
{ //如果栈不空并且不等于当前出站序列中的数字,则必须再将后面的标号入栈
Push(S,in[i]);
print[k++]=1;
i++;
}
if(!is_Empty(S)&&Get_Top(S)==out[j])
{ //如果栈不为空,并且栈顶元素等于当前出站序列中的当前位置,则出栈,并让出站序列向后,开始处理下一个出站序列
Pop(S);
print[k++]=0;
j++;
}
}
if(!is_Empty(S)) //若栈不为空,说明有列车滞留在车站中,肯定不能实现题目给出的出站序列
printf("No.\n");
else
{
printf("Yes.\n");
for(i=1;i<=num*2;i++)
{
if(print[i]==1)
printf("in\n");
else
printf("out\n");
}
}
printf("FINISH\n");
}
}
int Get_Top(stack S)
{
return S.st[S.top-1];
}
void Pop(stack&S)
{
S.top--;
}
void Push(stack&S,int e)
{
S.st[S.top++]=e;
}
int is_Empty(stack S)
{
if(S.top==1)
return 1;
else
return 0;
}
void input(int*in,int*out)
{
char ch;
int i;
//进栈信息
i=1;
scanf("%c",&ch);
while(ch!=' ')
{
in[i]=ch-'0';
i++;
scanf("%c",&ch);
}
//出栈信息
scanf("%c",&ch);
i=1;
while(ch!='\n')
{
out[i]=ch-'0';
i++;
scanf("%c",&ch);
}
}
附上某位大神用C++写的代码
//AC代码: #include <iostream> #include <stack> using namespace std; int main() { int n; char in[100]; char out[100]; int flag[100]; //记录判断进站还是出站的标志 while(cin>>n) { cin>>in; cin>>out; stack<char> s;//模拟站台的栈 int i=0; //i代表进站序列的对应列车 int j=0; //j代表出站序列的对应列车 for(i;i<=n;) { if(s.empty()) //如果栈为空则处理第一个数据 { s.push(in[i]); //此处真的很神奇,即当in[i]已经不是火车序列时,in[i]="\0"push不进去的,但又保证了i++推出循环 flag[i+j] = 0; i++; //第一个数据入栈,计数器加一 } if(!s.empty()&&s.top()!=out[j])//如果栈不空并且不等于当前出站序列中的数字,则必须再将后面的标号入栈 { s.push(in[i]); flag[i+j] = 0; i++; } if(!s.empty()&&s.top()==out[j]) { s.pop(); flag[i+j] = 1; j++; } //如果栈不为空,并且栈顶元素等于当前出站序列中的当前位置,则出栈,并让出站序列向后,开始处理下一个出站序列 } if(s.empty()) //若栈为空,证明全部列车都已经出站,所以题目给出的出站序列有可能实现 { cout<<"Yes."<<endl; for(i=0;i<2*n;i++) { if(flag[i]!=1)cout<<"in"<<endl; else cout<<"out"<<endl; } cout<<"FINISH"<<endl; } else //若栈不为空,说明有列车滞留在车站中,肯定不能实现题目给出的出站序列 { cout<<"No."<<endl; cout<<"FINISH"<<endl; } } return 0; }