模拟题。

这题第一个障碍是现在少见的循环电梯 ('pater-noster' elevator)

"The building has `pater-noster' elevator, i.e. elevator build up from several cabins running all around."

这种叫做 paster-noster 的电梯是 running all around 的,如动画所示,题目中费解的地方便清楚了。(欲知详情,请往维基百科)

第二个难点:模拟

模拟的核心是排队——等电梯或等房间

一开始可能感觉无从下手,模拟题的分析方法最主要的是分析事件。

准确地说,这道题有且仅有两个事件

排队等候(wating in queue)

行动(progress)

题目要求输出的是特工的活动记录(record)

solution:

1.用结构体表示事件:排队等候E,行动S

2.将电梯也看做房间编号是XX00

3.用优先队列维护排队等候的序列priority_queue<E, vector<E> > que,为此还需定义小于(<)运算符

bool operator < (const E& a,  const E& b){ ...}

4.维护vector<S> record[26]:特工的行动序列

5.房间状态的维护

(1)room[11][11] :房间空闲的起始时刻,初始化为0,模拟过程中要不断更新

(2)updated[11][11]: updated[i][j]表示room[i][j]是否更新过

若当前等待事件的目标房间(或电梯)更新过,则要将当前等待事件再次入队

6.处理过程中时间统一化成秒,输出时再转化成指定的格式

7.其他细节见代码

网上见到的题解大多代码过长,可读性差,我自己写了个比较简明的版本,200行多一点

#include<bits/stdc++.h>
using namespace std; typedef pair<int,int> P; int room[][]; //room[i][j]:房间空闲的起始时刻
bool updated[][]; //起始时刻是否已更新 vector<P> agent[]; int time[], sta[]; int done[];//已经访问的房间数目 struct S //行程
{
int des;
int cost;
S(int des, int cost):des(des), cost(cost){}
}; struct E //排队
{
int code;
int beg;
int pos;
E(int code, int beg, int pos):code(code), beg(beg), pos(pos){};
}; bool operator <(const E &a, const E &b)
{
//两人不是站在同一队列中等待
if(a.pos!=b.pos) return a.beg > b.beg;
//两人同时到达
if(a.beg==b.beg) return a.code > b.code; int f=a.pos/, r=a.pos%; //等电梯
if(a.pos%==)
{
int t1=(a.beg%?(a.beg/+)*:a.beg);
int t2=(b.beg%?(b.beg/+)*:b.beg);
//两人乘同一班电梯,资历高的先进
if((t1<=room[f][r]&&t2<=room[f][r])||t1==t2)
return a.code>b.code;
return t1>t2;
}
else //等房间
{
//两人都得等,资历高的先进
if(a.beg<=room[f][r]&&b.beg<=room[f][r]) return a.code>b.code; //!room[f][r]更新会影响这种比较
//至少有一个人不用等,先到的先进
else return a.beg > b.beg;
}
} priority_queue<E, vector<E> >que; //排队
vector<S> record[]; //行程 void input()
{
FILE* fp=stdin; //提交时改成stdin
char c;
int h, m, s, pos, dur;
while(fscanf(fp," %[A-Z] ",&c))
{
int idx=c-'A';
fscanf(fp,"%d:%d:%d",&h,&m,&s);
time[idx]=sta[idx]=*h+*m+s; while(fscanf(fp,"%d",&pos),pos)
{
fscanf(fp,"%d",&dur);
agent[idx].push_back(P(pos, dur));
}
agent[idx].push_back(P(pos, )); //! Exit
}
} void init()
{
for(int i=; i<; i++)
{
if(!agent[i].size()) continue;
if(agent[i][].first/==)
record[i].push_back(S(agent[i][].first,));//往一层某房间
else record[i].push_back(S(,));//往一层电梯
time[i]+=;
que.push(E(i,time[i],record[i].back().des));
}
} void simulator()
{
int wait, id, cost, to, f, r;
while(!que.empty())
{
E e=que.top();
que.pop();
id=e.code;
f=e.pos/;
r=e.pos%;
if(updated[f][r])
{
que.push(e);
updated[f][r]=false;
continue;
} if(r==) //等电梯
{
if(e.beg<=room[f][r]) wait=room[f][r]-e.beg;
else wait=(e.beg%? -e.beg%: );
if(wait) record[id].push_back(S(e.pos, wait));
time[id]+=wait;
room[f][r]=time[id]+;
updated[f][r]=true;
to=agent[id][done[id]].first;
if(to==) //!Exit
{
cost=*(e.pos/-);
record[id].push_back(S(, cost));
record[id].push_back(S(to,));
continue;
}
cost=*(max(to/,e.pos/)-min(to/,e.pos/));
record[id].push_back(S(to/*, cost)); //在电梯里
time[id]+=cost;
record[id].push_back(S(to, )); //往房间
time[id]+=;
que.push(E(id,time[id],to));
}
else //等房间
{
wait=max(room[f][r]-e.beg,);
if(wait) record[id].push_back(S(e.pos,wait));
time[id]+=wait;
cost=agent[id][done[id]].second;
record[id].push_back(S(-e.pos, cost)); //取反
time[id]+=cost; room[f][r]=time[id];
updated[f][r]=true; done[id]++;
to=agent[id][done[id]].first;
if(to==&&f==) //!Exit
{
record[id].push_back(S(to, ));
continue;
}
if(to/!=f) to=f*; //需等电梯
record[id].push_back(S(to, )); //往电梯
time[id]+=;
que.push(E(id,time[id],to));
}
}
} void t_p(int t)
{
int h=t/, m=(t%)/, s=t%%;
printf("%02d:%02d:%02d ",h,m,s);
} void e_p(int pre, int cur)
{
if(pre==) {printf("Entry\n"); return;}
if(cur==) {printf("Exit\n"); return;}
if(cur<) {printf("Stay in room %04d\n",-cur); return;}
if(pre==cur)
{
if(cur%==) printf("Waiting in elevator queue\n");
else printf("Waiting in front of room %04d\n",cur);
return;
}
if(pre%==&&cur%==) {printf("Stay in elevator\n"); return;};
if(pre<)
{
if(cur%==) printf("Transfer from room %04d to elevator\n",-pre);
else printf("Transfer from room %04d to room %04d\n",-pre, cur);
return;
}
else printf("Transfer from elevator to room %04d\n",cur);
} void output()
{
int pre_pos, cur_pos, t;
for(int i=; i<; i++)
{
if(!record[i].size()) continue;
t=sta[i];
pre_pos=; printf("%c\n",'A'+i);
for(int j=; j!=record[i].size(); j++)
{
t_p(t);
t_p(t+=record[i][j].cost);
cur_pos=record[i][j].des;
e_p(pre_pos, cur_pos);
pre_pos=cur_pos;
}
printf("\n");
}
} int main()
{
input();
init();
simulator();
output();
return ;
}

POJ #1025 Department的更多相关文章

  1. POJ #2448 A New Operating System

    Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 1165   Accepted: 110 Case Time Limit: ...

  2. hihoCoder 1401 Registration

    多队列模拟. 与POJ #1025 Department类似, 不过简化很多. 貌似这类模拟题经常出现. 用STL中的优先队列 (priority_queue<>) 很好写. 这题我写得很 ...

  3. POJ题目排序的Java程序

    POJ 排序的思想就是根据选取范围的题目的totalSubmittedNumber和totalAcceptedNumber计算一个avgAcceptRate. 每一道题都有一个value,value ...

  4. POJ 1065 Wooden Sticks(zoj 1025) 最长单调子序列

    POJ :http://poj.org/problem?id=1065 ZOJ: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId= ...

  5. POJ 1065 & ZOJ 1025

    #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> ...

  6. poj 1266 Cover an Arc.

    http://poj.org/problem?id=1266 Cover an Arc. Time Limit: 1000MS   Memory Limit: 10000K Total Submiss ...

  7. [划分树] POJ 2104 K-th Number

    K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 51732   Accepted: 17722 Ca ...

  8. 【POJ】2104 K-th Number(区间k大+主席树)

    http://poj.org/problem?id=2104 裸题不说.主席树水过. #include <cstdio> #include <iostream> #includ ...

  9. POJ 2104&HDU 2665 Kth number(主席树入门+离散化)

    K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 50247   Accepted: 17101 Ca ...

随机推荐

  1. 陆教授浅谈5G毫米波手机天线技术的发展现状和未来的应用场景

    近日,香港城大电子工程学系讲座教授陆贵文教授荣获英国皇家工程院院士荣衔,以表彰他在推动天线研究的卓越贡献.他研发的天线由L形探针馈电微带天线.磁电耦极天线,以至5G毫米波手机天线等技术,均在天线领域影 ...

  2. CPP-基础:新标准 C++iostream

    在新的标准 C++ iostream 库中: 1. open 函数不采用第三个参数(保护参数). 2. 无法从文件句柄创建流. 3. 除了几个例外,新的标准 C++ 库中的所有名称都在 std 命名空 ...

  3. QT5:介绍

    一.简介 QT是一个跨平台的C++开发库,主要用来开发图形用户界面(Graphical User Interface,GUI) QT除了可以绘制漂亮的界面(包括控件/布局/交互),还可以多线程/访问数 ...

  4. 《毛毛虫组》【Alpha】Scrum meeting 2

    第二天 日期:2019/6/15 1.1 今日完成任务情况以及遇到的问题. 今日完成任务情况: (1)对数据库表进行完善及测试: (2)定义Regex类的IsMatch()方法: (3)进行这一模块代 ...

  5. C#数组排序方法

    在C#中常用的数组排序的方法有:选择排序法.冒泡排序法.插入排序法和希尔排序法等. 一.选择排序法 using System;using System.Collections.Generic;usin ...

  6. TCP、UDP的区别

    TCP(传输控制协议): 1)提供IP环境下的数据可靠传输(一台计算机发出的字节流会无差错的发往网络上的其他计算机,而且计算机A接收数据包的时候,也会向计算机B回发数据包,这也会产生部分通信量),有效 ...

  7. 【转】VC自定义消息

    MFC一般可利用ClassWizard类向导添加消息和消息处理函数,但用户自定义消息必须手工输入,现将vc自定义消息方法步骤记录如下: (1)定义消息 利用#define语句直接定义用户自己的消息(既 ...

  8. 【转】浅谈对主成分分析(PCA)算法的理解

    以前对PCA算法有过一段时间的研究,但没整理成文章,最近项目又打算用到PCA算法,故趁热打铁整理下PCA算法的知识.本文观点旨在抛砖引玉,不是权威,更不能尽信,只是本人的一点体会. 主成分分析(PCA ...

  9. python入门:py2.x里面除法或乘法这么写就可以计算小数点后面结果

    #!/usr/bin/env python # -*- coding:utf-8 -*- #py2.x里面除法或乘法这么写就可以计算小数点后面结果,更精确future(未来,译音:非忧车) divis ...

  10. 点击tr实现选择checkbox功能,点击checkobx的时候阻止冒泡事件, jquery给checkbox添加checked属性或去掉checked属性不能使checkobx改变状态

    给tr添加点击事件,使用find方法查找tr下的所有层级的元素,children只查找下一层级的元素,所以使用find.find的返回值为jquery对象,在这个项目中不知道为什么使用jquery给c ...