简单摘抄一下有关队列的概念、算法、基本代码语句和应用场景。
概念:
队列指的是一种先进先出的容器;
队列总是从队尾加入元素,而从队首移除元素。一般来说需要一个队首指针front指向队首元素的前一个位置,使用一个队尾指针指向队尾元素;
queue容器内的访问:
队列本身作为一种先进先出的限制性数据结构,在STL中只能通过front()来访问队首元素,或是通过back()来访问队尾元素。
应用场景
n个窗口,每个窗口可以排队m人。有k位用户需要服务,给出了每位用户需要的minute数,所有客户在8点开始服务,如果有窗口还没排满就入队,否则就在黄线外等候。如果有某一列有一个用户走了服务完毕了,黄线外的人就进来一个。如果同时就选窗口数小的。求q个人的服务结束时间。
如果一个客户在17:00以及以后还没有开始服务(此处不是结束服务是开始17:00)就不再服务输出sorry;如果这个服务已经开始了,无论时间多长都要等他服务完毕。
1、给每个窗口建立结构
2、窗口结构含有等待队列、队首出队时间和队尾出队时间
3、将黄线内和黄线外分开讨论
struct node {
int poptime,endtime; // 队首出队时间 和 队尾出队时间
queue<int> q;
};
int main(){
int n,m,k,q,index=1;
scanf("%d %d %d %d",&n,&m,&k,&q); //窗口数、每个窗口黄线内人数、总人数、查询个数
vector <int> time(k+1), result(k+1); //每个人的办理时间和办理后
for(int i = 1;i<=k;i++){ //输入办理时间
scanf("%d",&time[i]);
}
vector<node> window(n+1);
vector<bool> sorry(k+1, false); // 初始化k个人的状态
for (int i=1;i<=m;i++){ //遍历黄线内的人
for (int j =1 ;j<=n;j++){
if (index<=k){
window[j].q.push(time[index]); //将第index个人的办理时间加入到队列
if (window[j].endtime>=540){ // 如果原来的队尾出队时间越界,则改变状态
sorry[index]=true;
}
window[j].endtime += time[index]; //将第index个人的办理时间加入到队尾出队队列
if (i==1){
window[j].poptime=window[j].endtime; //队列里只有一个人,则队首出队时间和对队尾出队时间一样
}
result[index]=window[j].endtime;
index++; //下一个人
}
}
}
while (index<=k){ //遍历余下每一个人
int tempmin = window[1].poptime,tempwindow = 1;
for(int i=2;i<=n;i++){
if (window[i].poptime<tempmin){ //找出队首出队时间最小的那个队
tempwindow= i;
tempmin=window[i].poptime;
}
}
window[tempwindow].q.pop();
window[tempwindow].q.push(time[index]); //将第index个人的办理时间加入到队列
window[tempwindow].poptime +=window[tempwindow].q.front(); //改变 队首出队时间
if (window[tempwindow].endtime>=540){ //判断 队尾出队时间是否越界
sorry[index]=true;
}
window[tempwindow].endtime+=time[index]; //将第index个人的办理时间加入到队尾出队队列
result[index]=window[tempwindow].endtime; //第 index个人办理后时间
index++;
}
for (int i=1;i<=q;i++){ // 按查询输出模块
int query,minute;
scanf("%d",&query);
minute= result[query];
if (sorry[query]==true){
printf("Sorry\n");
}
else {
printf("%02d:%02d\n",(minute+480)/60,(minute+480)%60);
}
}
return 0;
}
np为老鼠的数量,ng为每组最多g个老鼠。先给出np个老鼠的重量,再给出老鼠的初始顺序(第i名的老鼠是第j号,j从0开始)。每ng个老鼠分为一组,对于每组老鼠,选出最重的那个,晋级下一轮比赛,然后依次再以np个老鼠一组分类,然后选出重量最大的。。。直到只剩下一只老鼠,排名为1.输出为老鼠的排名,这个排名是按照原输入老鼠的顺序输出的~
struct node{ //对老鼠建立结构,重量,排名后下标,排名前下标,rank是最终输出的排名
int weight,index,rank,index0;
};
bool cmp(node a,node b){ //输出的以原始输入的顺序输出
return a.index0 <b.index0;
}
int main(){
int Np,Ng; //输入老鼠总数和每组老鼠数量
scanf("%d %d",&Np,&Ng);
vector<int> n(Np);
vector<node> w(Np);
for (int i=0;i<Np;i++){
scanf("%d",&n[i]); //输入老鼠重量数据
}
int num;
for (int i=0;i<Np;i++){ //初始化老鼠信息
scanf("%d",&num);
w[i].weight=n[num]; //老鼠重量
w[i].index = i; //当前下标
w[i].index0 = num; //原始下标
}
queue<node> q;
for (int i=0;i<Np;i++){ //将每一只老鼠的信息加入队列
q.push(w[i]);
}
while (!q.empty() ){
int size = q.size() ;
if (size==1){
node temp = q.front() ;
w[temp.index].rank=1;
break;
}
int group =size/Ng; //计算分组数
if (size%Ng!=0){
group++;
}
node maxnode; //记录质量最大的老鼠的编号
int maxn=-1; //记录最大质量
int cnt=0; //当前组内数量
for (int i =0;i<size;i++){
node temp = q.front() ; //提取队首元素
w[temp.index].rank=1+group;
q.pop() ; //出队操作
cnt++;
if (temp.weight>maxn){ //找出最大质量
maxn=temp.weight ;
maxnode = temp; //找出最大质量老鼠的编号
}
if (cnt==Ng||i==size-1){
cnt=0;
maxn=-1;
q.push(maxnode); //使得组内最大老鼠重新入队,因为先进先出,重新入队的在队列最后
}
}
}
sort(w.begin() ,w.end(),cmp); //按原始排序进行排序
for (int i=0;i<Np;i++){
if (i!=0){
printf(" ");
}
printf("%d",w[i].rank); //输出最终排名
}
return 0;
}