一、序列调度
有一个N个数的序列A:1,2,……,N。有一个后进先出容器D,容器的容量为C。如果给出一个由1到N组成的序列,那么可否由A使用容器D的插入和删除操作得到。
输入格式:
第1行,2个整数T和C,空格分隔,分别表示询问的组数和容器的容量,1≤T≤10,1≤C≤N。
第2到T+1行,每行的第1个整数N,表示序列的元素数,1≤N≤10000。接下来N个整数,表示询问的序列。
输出格式:
T行。若第i组的序列能得到,第i行输出Yes;否则,第i行输出No,1≤i≤T。
输入样例:
在这里给出一组输入。例如:
2 2
5 1 2 5 4 3
4 1 3 2 4
输出样例:
在这里给出相应的输出。例如:
No
Yes
这个题目我是用模拟栈解的,在做这个题时,需要搞清楚序列A进栈的元素、后来进来的数据、栈顶元素之间的关系。
(1)、栈顶元素和读入的数据元素相等,弹栈并读下一个数据元素,如果此时的栈顶元素依然和数据元素相等则继续弹栈,直到栈顶元素和数据元素不再相等为止。
(2)、(1)处理的是弹栈的工作,现在考虑进栈:
试着思考这个序列: 2 4 1 3
A序列第一个元素是1,所以每次入栈总是从1 开始
1与2不等,入栈,此时栈中元素:1
2与1不相等入栈,栈中元素:1,2(此时栈顶元素与2相等,弹栈,栈中元素:1)
4与1 不相等 但是此时按照序列顺序应该3入栈,栈中元素:1, 3
接下来的入的数据是1,我们发现这是不可能与栈顶元素相等的,因为此时的 3>1 !而序列只会向后推动,这个1 是永远也拿不到了。
所以我们在这部进行一个讨论:此时该入栈的元素和读入的数据元素作比较,如果该入栈的这个元素大于数据元素,那么最后一定会造成栈溢出,不能得到这个序列。
(3)、由(2)我们讨论得到下一个该入栈的元素是不能大于读入的数据元素的,所以只能是≤关系,等于的话好说,相当于入栈马上出栈,我们讨论小于的情况。
看这个序列: 2 4 3 1
1入栈,栈中元素:1
2入栈 2=2,弹栈,栈中元素:1
3入栈,3!=4 栈中元素:1, 3
4入栈 , 4=4,弹出4 ,栈中元素:1 ,3 栈顶元素3=3,弹栈,栈中元素:1 ,栈顶元素1=1, 弹栈 栈空,序列读完,可以得到序列(注意这里我没有设置栈的大小)
我们发现栈顶元素小于读入数据元素时,会一直进栈,直到栈顶和读入数据元素相等。
(4)、写到这里我们只需要再讨论栈中元素个数是否超过规定大小就可以。
下面是代码实现:
#include<iostream>
#include<stack>
#define maxsize 10005
using namespace std;
int main(){
bool flag;
stack<int> t;
int data[maxsize];
int i,j,k;
int T,C,N,x,cnt=0,pointer=1; //pointer是序列A的指针
scanf("%d %d",&T,&C);
for(k=1;k<=T;k++){
scanf("%d",&N);
flag=1;
for(i=1;i<=N;i++){
scanf("%d",&data[i]);
}
i=1; while(!t.empty()) t.pop();
for(j=1;j<=N;j++){
if(!t.empty()&&t.top()==data[j]){
t.pop();
continue;
}
if(i>data[j]){
flag=0;
printf("No\n");
break;
}
for(;i<