栈与队列

STL 栈与队列

第一题:Blah数集
题目 :
对于以a为基的集合Ba定义如下:
(1) 是集合a的Ba基,且a是Ba的第一个元素;
(2)如果x在集合Ba中,则2x+1和3x+1也都在集合Ba 中;
(3)没有其他元素在集合Ba 中了。
想知道如果将集合Ba中元素按照升序排列,第n个元素会是多少?
**分析:**我们知道一个x可以产生出2x+1和3x+1那么每次的第一个2x+1和第二个2x+1比大小,小的放前面,一样3x+1也要比,所以放到n个数是就可以了。
代码:

#include <bits/stdc++.h>
using namespace std;
queue<int> q1;
queue<int> q2;
int main()
{
	int n,m;
	int x;
	while(cin>>n>>m)
	{
		x=n; 
		q1.push(x*2+1);
		q2.push(x*3+1);
		for(int i=1;i<m;i++)
		{
			if(q1.front()<q2.front())
			{
				x=q1.front();
				q1.pop();
			}
			else if(q1.front()==q2.front())
			{
				x=q1.front();
				q1.pop();
				q2.pop();
			}
			else
			{
				x=q2.front();
				q2.pop();
			}
			q1.push(x*2+1);
			q2.push(x*3+1);
		}
		cout<<x<<endl;	 
		if(!q1.empty())
		{
			while(!q1.empty())
			{
				q1.pop();
			}
		}
		if(!q2.empty())
		{
			while(!q2.empty())
			{
				q2.pop();
			}
		}
	}
    return 0;
}

第二题:奇怪的电梯
**题目 :**大楼的每一层楼都可以停电梯,而且第 i 层楼(1<=i<=N)上有一个数字Ki(0<=Ki<=N)。 电梯只有四个按钮:开,关,上,下。上下的层数等于当前楼层上的那个数字。当然,如果 不能满足要求,相应的按钮就会失灵。例如:3 3 1 2 5 代表了 Ki(K1=3,K2=3,……),从一 楼开始。在一楼,按“上”可以到 4 楼,按“下”是不起作用的,因为没有-2 楼。那么, 从 A 楼到 B 楼至少要按几次按钮呢?
**分析:**从这个数开始,两个方向,上和下。上/下:队列这个数加/减上这个数,并且不大于范围,判断是否是B,是就输出按了几次,不是就入队列。
代码:

#include<bits/stdc++.h>
using namespace std;
typedef struct
{
	int step;
	int floor;
} dt;
queue<dt>lift;
bool flag[2000],f;
int main()
{
	int n,a,b,k[2000];
	dt s,e;
	cin>>n>>a>>b;
	for(int i=1;i<=n;i++)
	{
		cin>>k[i];
	}
	s.step=0;s.floor=a;
	lift.push(s);
	while(!lift.empty())
	{
		s=lift.front();
		lift.pop();
		if(s.floor==b)
		{
			cout<<s.step<<endl;
			f=1;
			break;
		}
		if(s.floor+k[s.floor]<=n&&!flag[s.floor+k[s.floor]])
		{
			e.floor=s.floor+k[s.floor];
			e.step=s.step+1;
			flag[e.floor]=1;
			lift.push(e); 
		}
		if(s.floor-k[s.floor]>=1&&!flag[s.floor-k[s.floor]])
		{
			e.floor=s.floor-k[s.floor];
			e.step=s.step+1;
			flag[e.floor]=1;
			lift.push(e); 
		}
	}
	if(f==0) cout<<"-1"<<endl;
	return 0;
}

第三题:字符串匹配
题目 : 字符串中只含有括号 (),[],<>,{},判断输入的字符串中括号是否匹配。如果括号有互相包含的形式,从内到外必须是<>,(),[],{},例如。输入: [()] 输出:YES,而输入([]),([)]都应该输出NO。
分析: 可以用优先级下手,判断是否先是大的优先级,否则就判断下一个小的优先级,然后看ascall码表
详见:Ascall码表,发现任何括号都有规律,这样就跟着优先级判断就行了。
代码:

#include<bits/stdc++.h>
using namespace std;
int n,m,i;
char c,str[300],s[300];
int main()
{
    cin>>m;
    s[0]=127;
    while(m--)
    {
        cin>>str;
        i=n=0;
        while(c=str[i++])
        {
            if(c=='<') s[++n]=c;
            else if(c=='('&&s[n]!='<') s[++n]=c;
                 else if(c=='['&&s[n]>=c) s[++n]=c;
                      else if(c=='{'&&s[n]>=c) s[++n]=c;
                           else if((c+s[n])/2+1==c) n--;
                                else
                                {
                                    n=-1;
                                    break;
                                }
        }
        if(n==0) cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
    return 0;
}`

第四题:计算
**题目 :**小明在你的帮助下,破密了Ferrari设的密码门,正要往前走,突然又出现了一个密码门,门上有一个算式,其中只有“(”,“)”,“0-9”,“+”,“-”,“*”,“/”,“^”,求出的值就是密码。小明数学学得不好,还需你帮他的忙。(“/”用整数除法)。
分析: 首先要维护两个栈,我这里用数组模拟栈,其次括号优先级和运算符优先级,再是各种运算符。
代码:

#include<bits/stdc++.h>
using namespace std;
int number[301];   
char symbol[301]; 
string s,t;      
int i,j,p;   
 
int POW(int a,int b)  
{
	int j,t=1;
	for(j=1;j<=b;j++) t*=a;
	return t;
}
 
void push()       
{
    p++;
    symbol[p]=s[i];
}
 
void pop() 
{
    p--;                 
    switch(symbol[p+1])  
    {
         case '+' : number[p]+=number[p+1]; break;
         case '-' : number[p]-=number[p+1]; break;
         case '*' : number[p]*=number[p+1]; break;
         case '/' : number[p]/=number[p+1]; break;  
         case'^'  : number[p]=POW(number[p],number[p+1]);break;		        
    }
}
bool can()         
{ 
    if((s[i]=='+' || s[i]=='-') && (symbol[p]!='(' )) return true; 
    if((s[i]=='*' || s[i]=='/') && (symbol[p]=='^' ||symbol[p]=='*' || symbol[p]=='/')) return true;
    if(s[i]=='^' && symbol[p]=='^') return true;
    return false;   
}

int main()
{
    cin>>s;
    s="("+s+")";  
    i=0; p=0;
     
    while(i<s.size())      
    {
        while(s[i]=='(' )  
        {
            push();         
            i++;
        } 
        
        if(s[i]>='0' && s[i]<='9')
        {
           j=i;
           do             
           {                   
              i++;
           }while(s[i]>='0' && s[i]<='9');
     
           t=s.substr(j,i-j);                             
           sscanf(t.c_str(),"%d",&number[p]);   
        }               
        if(s[i]==')')  
        {
            while(symbol[p]!='(') pop();  
            p--;                       
            number[p]=number[p+1];       
        }
        
        else                    
        {
            while(can()) pop();  
            push();              
        }
        i++;                      
    }
    cout<<number[0]<<endl;        
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值