洛谷 P1844 阅览室_NOI导刊2011提高(12)

来源:互联网 发布:美工运营对骂gif 编辑:程序博客网 时间:2024/05/16 08:18

题目描述
一个阅览室每天都要接待大批读者。阅览室开门时间是O,关门时间是T。每位读者的到达时间都不一样,并且想要阅读的刊物不超过5本。每位读者心里对自己想看的刊物都有一个排位,到达之后他会先去找自己最想看的刊物,如果找不到则去找其次想看的刊物。如果找不到任何他想看的刊物,他会开始等待,直到有一本以上的他想看的刊物被人放回原处。当然,他会先去拿其中自己最想看的刊物。当他看完某一本刊物后,就把它放回原处,接着去找自己没看过的最想看的刊物。如此下去,直到看完所有他想看的刊物为止。矛盾出现在两个人同时想要拿同一本刊物的时候。阅览室为了避免读者之间出现争执,作了一个规定,读者每次在开始等待时先去服务台做一次登记。如果两个人都同时想要一本刊物,那么先登记的读者将得到这本刊物。如果两个人同时登记,那么先到达阅览室的读者将得到刊物。没得到的人就只能去找其他的刊物看。阅览室关门时,所有读者都将被强迫离开阅览室,不再允许继续阅读。
现在阅览室想做一个统计调查,你被要求写一个程序来模拟这个过程计算出所有刊物被阅读的总次数。当某个读者开始阅读某本刊物时,该刊物的被阅读次数就加1,无论这本刊物最后有没有被读完。
输入输出格式
输入格式:
输入包括了多个测试数据。每个测试数据开头是两个整数T和n(1≤n≤100),分别表示图书馆关门时间和读者总数。接下来按照读者的到达时间先后依次给出了每位读者的具体描述。每个读者描述开头是一个整数t(0 ≤ t < T),表示该读者到达时间。接下来一行开头是一个整数k(1≤k≤5),表示该读者想要看的刊物数目。之后跟着2k个整数按照读者想要阅读的刊物的顺序依次给出了刊物的描述。其中第2i-1个整数表示刊物的编号s(0≤s<1000),第2i个整数表示该读者读完这本刊物所需的时间。
输出格式:
对于每个测试数据,在单独一行里输出所有刊物被阅读的总次数。
输入输出样例
输入样例#1:
10 4
1
2 1 4 2 5
3
1 2 4
7
3 2 2 1 3 3 2
9
1 4 2
输出样例#1:
5

略微有点恶心的模拟,记录一下这本书下次可以被拿去看的时间和这个人下次来取书的时间就好,再就是细节,代码注释应该很清楚了。

#include<iostream>#include<cstring>#include<cmath>#include<cstdio>#include<cstdlib>#include<algorithm>using namespace std;int t, n, b[1010];long long Ans;struct People {    int com, nxt, num;//来的时间、下次出现时间、书本数     int a[6], b[6];//书本序号及阅读消耗时间     bool Jud[6];// 记录是否读过 }p[110];inline void read(int &x){    x=0; int f=1; char c=getchar();    while(c>'9'||c<'0'){ if(c=='-')f=-1; c=getchar(); }    while(c>='0'&&c<='9'){ x=x*10+c-'0'; c=getchar(); } x*=f;}int main(int argc,char *argv[]){    read(t),read(n);    for(int i=1; i<=n; ++i){        read(p[i].com),read(p[i].num);        p[i].nxt = p[i].com;//nxt  表示 这个人下次来的时间         for(int j=1; j<=p[i].num; ++j)            read(p[i].a[j]), read(p[i].b[j]);    }    for(int i=0; i<=t-1; ++i) // t 时  关门         for(int j=1; j<=n; ++j){            if(p[j].nxt > i) continue;            bool flag = false;// 能否直接拿到一本想看的(想看的书有没有空闲的)            for(int k=1; k<=p[j].num; ++k)                if(b[ p[j].a[k] ] <= i && !p[j].Jud[k]){                    p[j].Jud[k] = flag = true;//标记 读过                     b[ p[j].a[k] ] = p[j].nxt = i + p[j].b[k];// 更新人下一次出现的时间                     //b[ p[j].a[k] ] = i + p[j].b[k];// 更新书的下次出现 时间                    ++Ans ;                    break;                 }            if(! flag) {                int Min = 1e9 + 7,g;                for(int k=1; k<=p[j].num; ++k)// 找一本能最快出现的                     if(Min > b[ p[j].a[k] ] && !p[j].Jud[k]) Min = b[ p[j].a[k] ], g = k;                if(Min < t){// 这段时间他没事 会一直等着 所以他想看的书里面最快出现的一定到时候先给他                     p[j].Jud[g] = true;                    b[ p[j].a[g] ] += p[j].b[g];                    p[j].nxt = b[ p[j].a[g] ];                    ++Ans;                }            }        }    printf("%lld\n", Ans);    return 0;}

这两天迷上了代码无限敲空格, 手速还慢,怎么破。。

原创粉丝点击