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為Falsechar 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{//用鏈表實現,鏈表中儲存隊列以及該隊列的IDint 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儲存隊列IDfor(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;}