hdu1873(看病要排隊)循環隊列害死我了
點擊打開杭電1873
Problem Description
看病要排隊這個是地球人都知道的常識。
只是經過細心的0068的觀察。他發現了醫院裏排隊還是有講究的。0068所去的醫院有三個醫生(汗。這麽少)同一時候看病。而看病的人病情有輕重,所以不能依據簡單的先來先服務的原則。所以醫院對每種病情規定了10種不同的優先級。級別為10的優先權最高,級別為1的優先權最低。醫生在看病時。則會在他的隊伍裏面選擇一個優先權最高的人進行診治。假設遇到兩個優先權一樣的病人的話。則選擇最早來排隊的病人。
如今就請你幫助醫院模擬這個看病過程。
Input
輸入數據包括多組測試,請處理到文件結束。
每組數據第一行有一個正整數N(0<N<2000)表示發生事件的數目。
接下來有N行分別表示發生的事件。
一共同擁有兩種事件:
1:"IN A B",表示有一個擁有優先級B的病人要求醫生A診治。(0<A<=3,0<B<=10)
2:"OUT A",表示醫生A進行了一次診治,診治完成後,病人出院。(0<A<=3)
Output
對於每一個"OUT A"事件,請在一行裏面輸出被診治人的編號ID。假設該事件時無病人須要診治。則輸出"EMPTY"。
診治人的編號ID的定義為:在一組測試中,"IN A B"事件發生第K次時,進來的病人ID即為K。從1開始編號。
Sample Input
7 IN 1 1 IN 1 2 OUT 1 OUT 2 IN 2 1 OUT 2 OUT 1 2 IN 1 1 OUT 1
Sample Output
2 EMPTY 3 1 1
思路:題意已經非常清楚了,能夠用隊列做這題。
因為初學隊列,不是了解非常深,這題或許也是他們所說的優先隊列。
依據題目要求,能夠申請三個隊列,分別進行操作。而對每一個隊列又要考慮優先級,所以在出隊列時。能夠先對隊列中的數據進行一次優先級排序。
僅僅是這裏不知道為什麽用優先隊列就是死都a只是去,用普通隊列就一次ac了。真的非常無語!!
!!
!
!(後面有提供幾組有幫助的測試數據)
註:1、要求輸出的不是優先級,別看錯了哦,而是第幾個進來的人的序列號
2、還要對優先級進行排序,別犯錯誤:找到別當前輸出的人的優先級高的,然後進行交換。這是錯誤的。
普通隊列(能ac):
import java.util.Scanner; public class P1873_2 { public static void main(String[] args) { Scanner sc=new Scanner(System.in); String s; int priority,num,count; PersonlQueue[] loopQueue=new PersonlQueue[4];//申請三個隊列,這裏的0不用 while(sc.hasNext()){ int n=sc.nextInt(); count=0; for(int i=1;i<4;i++){ loopQueue[i]=new PersonlQueue(); } for(int i=0;i<n;i++){ s=sc.next(); if(s.charAt(0)==‘I‘){//若是IN則直接入隊就可以 count++; num=sc.nextInt(); priority=sc.nextInt(); PPersonl p=new PPersonl(count,priority);//這是一個PPersonl類,就是存放每一個人的優先級,還有就是第幾個輸入的(這也是為什麽要單獨建一個類的原因) loopQueue[num].add(p);//入隊 }else{//出隊 num=sc.nextInt(); int a=loopQueue[num].pop(); if(a==0){ System.out.println("EMPTY"); }else{ System.out.println(a); } } } } } } class PPersonl{ int priority;//優先級 int count;//人的序列號(第幾個人) ,也就是要求要輸出的數 public PPersonl(int count, int priority) { this.count=count; this.priority=priority; } } class PersonlQueue{ int end; final int FRONT =0; PPersonl[] personl; public PersonlQueue(){ end = 0; personl=new PPersonl[10000]; } public void add(PPersonl p){//入隊 personl[end] = p; end++; } public int isEmpty(){//推斷是否為空,在此題並沒有什麽卵用 if(end<=0){ return 0; } return 1; } public int pop(){//出隊 if(end<=0){ return 0; } sort();//對優先級進行排序 int p = personl[FRONT].count; if(end>1){//隊首出隊,則後面的要補上來 for(int i=0;i<end;i++){ personl[i] = personl[i+1]; } } end--; return p; } private void sort() {//冒泡排序 for(int i=0;i<end-1;i++){ for(int j=0;j<end-i-1;j++){ if(personl[j].priority<personl[j+1].priority){ PPersonl temp=personl[j]; personl[j]=personl[j+1]; personl[j+1]=temp; } } } } }
循環隊列(wa):
package xjj; import java.util.Scanner; public class P1873 { public static void main(String[] args) { Scanner sc=new Scanner(System.in); String s; int priority,num,count; CirclingQueue[] loopQueue=new CirclingQueue[4]; while(sc.hasNext()){ int n=sc.nextInt(); count=0; for(int i=1;i<4;i++){ loopQueue[i]=new CirclingQueue(n); } for(int i=0;i<n;i++){ s=sc.next(); if(s.charAt(0)==‘I‘){ count++; num=sc.nextInt(); priority=sc.nextInt(); Personl p=new Personl(count,priority); loopQueue[num].add(p); }else{ num=sc.nextInt(); int a=loopQueue[num].pop(); if(a==0){ System.out.println("EMPTY"); }else{ System.out.println(a); } } } } } } class Personl{ int priority; int count; public Personl(int count, int priority) { this.count=count; this.priority=priority; } } class CirclingQueue{ int front; int end,n; Personl[] personl; public CirclingQueue(int n){ front =0; end = 0; this.n=n; personl=new Personl[this.n]; } public void add(Personl p){ personl[end] = p; end = (end+1)%n; } public int isEmpty(){ return front==end ?0 : 1; } public int pop(){ if(isEmpty()==0){ return 0; } sort(); int p = personl[front].count; front = (front+1)%n; return p; } private void sort() { for(int i=front;i<end-1;i++){ for(int j=front;j<end-i-1;j++){ if(personl[j].priority<personl[j+1].priority){ Personl temp=personl[j]; personl[j]=personl[j+1]; personl[j+1]=temp; } } } } }
測試數據:
7
IN 1 10
IN 1 5
IN 1 8
IN 1 4
OUT 1
OUT 1
OUT 1
結果:1 3 2
12
IN 1 10
IN 1 4
IN 1 4
IN 1 5
IN 1 4
IN 1 4
OUT 1
OUT 1
OUT 1
OUT 1
OUT 1
OUT 1
結果:1 4 2 3 5 6
hdu1873(看病要排隊)循環隊列害死我了