HDU_Steps8.1 栈,队列 HDU1702 HDU1022 HDU1237 HDU3228 HDU1873 HDU1509 HDU1870 HDU1387

8.1 基本都是简单的栈和队列

8.1.1 HDU1702 ACboy needs your help again!

入门题

8.1.2 HDU1022 Train Problem I

栈的入门题,了解概念就能做了,标记现在已经匹配到o1的第几列车了,o2从头开始,如果不匹配就放入栈中,匹配后出栈并比较栈顶与o1的下一辆,匹配继续出,不匹配就继续进栈 

8.1.3 HDU1237 简单计算器 

栈的入门题,一个数栈,一个符号栈。是数就入数栈,符号的话比较当前符号和栈顶符号优先级,决定是否运算,直到栈顶符号优先级大于当前符号优先级时就不继续运算并将当前符号进符号栈。最后数栈顶剩下的数就是结果。

8.1.4 HDU3228 Flipper 

一道栈的模拟题,每堆都是一个栈,合并时就将一个栈中的数依次出栈并且放到相邻的栈中,最后只剩下一个栈中有数,然后标记一下每张牌的朝向。最后根据栈中的顺序就很容易

#include<cstdio>
#include<string.h>
#include<stack>
using namespace std;
int main(){
	int n,n2,a,ar[105],cas=1;
	bool rs[105];//U为True,D为False
	char str[105];
	while(scanf("%d",&n),n){
		scanf("%s",str);
		for(int i=0;i<n;i++)rs[i]=(str[i]=='U')?true:false;
		
		int l=0,r=n-1;
		stack<int> st[105];
		for(int i=0;i<n;i++)st[i].push(i);
		
		scanf("%s",str);
		
		for(int i=0;i<n-1;i++){
			if(str[i]=='L'){
				l++;
				for(int j=0;j<l;j++)rs[j]=!rs[j];//更改面向
				
				while(!st[l-1].empty()){//合并牌堆
					st[l].push(st[l-1].top());
					st[l-1].pop();
				}
			}else{
				r--;
				for(int j=n-1;j>r;j--)rs[j]=!rs[j];
				
				while(!st[r+1].empty()){
					st[r].push(st[r+1].top());
					st[r+1].pop();
				}
			}
		}
		
		for(int i=0;i<n;i++){ar[i]=st[l].top();st[l].pop();}//储存牌堆的顺序,从顶向下
		
		printf("Pile %d\n",cas++);
		scanf("%d",&n2);
		while(n2--){
			scanf("%d",&a);
			printf("Card %d is a face ",a);
			a--;
			printf(rs[ar[a]]?"up ":"down ");
			printf("%d.\n",ar[a]+1);
		}
	}
	return 0;
}

8.1.5 HDU1873 看病要排队 

用优先队列就很EASY了。。以优先级为第一顺序,序号为第二顺序排序

8.1.6 HDU1509 Windows Message Queue 

跟上面那题差不多,优先队列很容易解决

8.1.7 HDU1870 愚人节的礼物

数括号。。左括号加,右括号减。。

8.1.8 HDU1387 Team Queue

我用链表实现的,每个节点是一个队列,并保存该队列ID。然后注意用哈希存储队列的ID。

#include<cstdio>
#include<queue>
#include<string.h>
using namespace std;
struct lb{//用链表实现,链表中保存队列以及该队列的ID
	int qid;
	queue<int> q;
	lb *next;
};

int cas=1,ts,k,tnum,opnum,hash[1000000];
char op[10];
lb *head=NULL;

void init(){
	memset(hash,0,sizeof hash);
	//释放空间
	while(head!=NULL){
		lb *p=head;
		head=head->next;
		delete(p);
	}
	//新建链表
	head=new lb;
	head->next=NULL;
}
int main(){
	while(scanf("%d",&ts),ts){
		init();
		//HASH储存队列ID
		for(int i=1;i<=ts;i++){
			scanf("%d",&k);
			while(k--){
				scanf("%d",&tnum);
				hash[tnum]=i;
			}
		}
		printf("Scenario #%d\n",cas++);
		while(scanf("%s",op)){
			if(strcmp(op,"STOP")==0){
				printf("\n");
				break;
			}else if(strcmp(op,"DEQUEUE")==0){
				lb *h=head->next;
				//去除链表第一个节点中队列的第一个元素,队列为空时删除该节点
				printf("%d\n",(h->q).front());
				(h->q).pop();
				if((h->q).empty()){
					lb *p=h;
					head->next=h->next;
					delete(p);
				}
			}else{
				int qr;
				scanf("%d",&qr);
				//找到ID对应的节点,没有的话就在后面新建一个节点
				lb *h=head;
				while(h->next!=NULL&&(h->qid!=hash[qr]))h=h->next;
				
				if(h->next==NULL&&h->qid!=hash[qr]){
					h->next=new lb;
					h=h->next;
					h->next=NULL;
					h->qid=hash[qr];
				}
				(h->q).push(qr);
			}
		}
	}
	return 0;
}



  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值