目录:
1.栈
2.队列
栈
A - A
现在有n个元素分别是1,2,3,...,n,我们想知道通过一个栈,在n次push/pop后,出栈序列可能是什么样的。例如n是5,那么入栈次序就是1,2,3,4,5,如果我们希望出栈次序同样是1,2,3,4,5,那只要每push一个数,就立即pop一个数。如果我们希望出栈次序是3,2,4,5,1,那么我们先让1,2,3入栈,然后pop出来3和2,接着4入栈后马上pop,再就是5入栈后马上pop,最后再把栈里的1pop出。再例如,如果我们希望出栈次序是5,4,1,2,3,这是办不到的,如果要让5最先出栈,那么出栈次序只可能是5,4,3,2,1
Input
输入由多块输入构成,每块的第一行是n,(1≤n≤1000),接着是多组测试数据,每组一行,每行由n个1到n的整数组成,直到某一行第一个数是0表示此输入块结束,然后是下一块数据。
当某一块的第一行的n是0的时候结束所有输入
Output
对每组数据,只要输出Yes或No,Yes表示能产生那样的出栈序列,No表示不能。 输入块与输入块之间要多输出一个空行分隔。注意对于最后一个n为0的输入块不要多输出空行。
Sample Input
5 1 2 3 4 5 5 4 1 2 3 0 6 6 5 4 3 2 1 0 0
Sample Output
Yes No Yes
思路:理想情况下,从小到大入栈,从大到小出栈,但是有些情况,一些小数提前出栈,但是比他小的数一点是按从大到小的顺序出栈,所以只要判断比这个出栈的数小的数是否按从大到小的顺序排就行了。
,偶然间阅读下面这篇博客 (9条消息) 入栈出栈规律·_u014424628的专栏-CSDN博客_栈的出栈序列口诀
代码实现:
#include<stdio.h>
int a[100000];
int main() {
int n;
while(~scanf("%d",&n)) {
if(n==0)
break;//n=0,结束所有输入
while(1) {
int t=0;
int g=0;
for(int i=0; i<n; i++) {
scanf("%d",&a[i]);
if(a[0]==0)//第一个数据为0,此输入块结束
{
g=1;
printf("\n");
break;
}
}
if(g==1)
break;
for(int k=0; k<n; k++) {
int g=a[k]; //小于a[k]的数一定是按照从大到小的顺序排序 5 4 3 2 1 4 5 3 2 1 3 5 4 2 1 2 3 5 4 1 1 5 4 3 2
for(int j=k+1; j<n; j++) {
if(a[k]>a[j]) {
if(g<a[j])
t=1;
else //筛选小于a[i]的数
g=a[j];
}
}
}
if(t==1)
printf("No\n");
if(t==0)
printf("Yes\n");
}
}
}
G-G
给出一个由1到n组成的无序数列,如果我们把这个序列看成是数字1~n出栈的顺序,并且入栈顺序是1, 2, 3, ..., n,请问操作时,栈内最多能有多少个元素?
Input
输入有多组数据。
每组数据的第一行为一个整数n代表由1到n的序列。 1<= n <=100。
第二行为n个用空格隔开的整数,范围是[1,n]。
Output
若此序列能由进栈,出栈得到,输出所使用的最小栈容,否则输出-1
Sample Input
5 1 2 3 4 5 4 3 2 1 4 6 6 5 4 1 3 2
Sample Output
1 3 -1
这个题目和上个题目类似,按照上面的模板稍加修改就可以实现,思路与上题差不多。
代码实现:
#include<stdio.h>
int main()
{
int n;
while(~scanf("%d",&n))
{
int t=0;
int a[10000];
int b[10000]={0};//计数,归零
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
for(int i=0;i<n;i++)
{
int g=a[i];
for(int j=i+1;j<n;j++)
{
if(a[i]>a[j])
{
if(g<a[j])
{
t=1;
}
else
{
g=a[j];
b[i]++;
}
}
}
}
if(t==0)
{
int max=b[0];
for(int i=0;i<n;i++)
{
if(b[i]>=max)
max=b[i];
}
printf("%d\n",max+1);
}
if(t==1)
printf("-1\n");
}
}
队列
E - E
宇神完成了栈的实验要求后,他又很是开心,刚要出去五排, 菌菌子突然问道老师让做的队列的那个实验你写完了么,宇神顿时大呼悲哉。。。。他给忘记了,怎么办。。明天就要上交实验报告了,你能帮他搞定么???
你需要完成三种操作1.enqueue x,将元素x插入队尾。2.dequeue,若队列非空,则删去队头元素,并输出该元素。3.query,从队头开始删除所有元素,并输出。
Input
本题有多组测试数据,每组数据首先输入一个T,接下来T行是T种对队列的操作。 (0< T < 100,0< x <= 500)
Output
每次执行dequeue操作时删除队头元素输出并换行,如果队列为空输出“this is empty!”并换行。
每次执行query操作时删除所有元素队列内所有元素并输出,每个元素占一行,如果栈为空输出“this is empty!”并换行。
每组数据后有一个空行。
Sample Input
10 enqueue 1 enqueue 2 enqueue 3 enqueue 4 query dequeue enqueue 1 dequeue query dequeue
Sample Output
1 2 3 4 this is empty! 1 this is empty! this is empty!
思路:按照题目进行操作
代码实现:
#include<stdio.h>
#include<string.h>
int top;
int front; //队首
int Q[100000];
char a[100000];
int x;
void push(int x) { //入队
Q[top]=x;
top++;
}
void pd()
{
if(top==front) //判断是否为空
printf("this is empty!\n");
}
int main() {
int n;
while(~scanf("%d",&n)) {
getchar(); //scanf遇回车结束
top=0; //最后的位置,归零
for(int i=0; i<n; i++) {
scanf("%s",a);
if(strcmp(a,"enqueue")==0 ){
scanf("%d",&x);
push(x);
}
if(strcmp(a,"query")==0)
{
pd();
while(front<top)//从前往后输出队列全部 元素
{
printf("%d\n",Q[front]);
Q[front]=0;
front++;
}
front=0; //归零
top=0; //归零
}
if(strcmp(a,"dequeue")==0)
{
pd();
if(top!=front)
{
printf("%d\n",Q[front]);
while(front<top) //输出队首元素
{
Q[front]=Q[front+1];
front++;
}
front=0;
top-=1; //总长度减一
}
}
}
printf("\n");
}
}
总结:做题目没有注重细节:输出格式经常不注意,需要归零的数据没有归零。