pku3326

统计时间,采用栈实现.对于每一个login,直接入栈;对于logout,将栈中的对于项弹出,注意要弹出的项不一定在栈顶,这就要用一个辅助栈,将弹出项上的各项先弹出,在弹出目标后,再将他们压入栈中,同时对于弹出项用其起始时间和结束时间与当前记录中的起止时间比较,保留最长的时间段.

最后查询时,根据要求的时间区间,对于要查询的人,依次检查其记录中的每一项,累计总时间即可.

Source:

#include<iostream>

#include<stack>

using namespace std;

 

struct Node {

    int in, out;

    struct Node *next;

};

 

struct Data {

    int t, nc, s;

};

 

stack<Data> current[10010];

Node da[10010];

Node* record[10010];

 

int main() {

    int t, ls, le, i, n, m, r, q, ms, te, ts;

    Node *temp, *p;

    while (1) {

       cin>>n>>m;

       if (n==0&& m==0)

           break;

       for (i=1; i<=m; ++i) {

           record[i]=NULL;

           da[i].in=2000;

           da[i].out=0;

       }

       cin>>r;

       for (; r>0; --r) {

           Data d, te;

           cin>>d.t>>d.nc>>ms>>d.s;

           if (d.s==0) {

 

              stack<Data> he;

              do {

                  te=current[ms].top();

                  current[ms].pop();

                  if (te.nc==d.nc) {

                     if(te.t<da[ms].in)da[ms].in=te.t;

                     if(d.t>da[ms].out)da[ms].out=d.t;

                     if (current[ms].empty() && he.empty()) {

                         temp=new Node();

                         temp->in=da[ms].in;

                         temp->out=da[ms].out;

                         temp->next=record[ms];

                         record[ms]=temp;

                         da[ms].in=2000;

                         da[ms].out=0;

                     }

                     break;

                  } else {

                     he.push(te);

                  }

              } while (1);

              while (!he.empty()) {

                  current[ms].push(he.top());

                  he.pop();

              }

           } else {

              current[ms].push(d);

           }

 

       }

 

//     for (i=1; i<=m; ++i) {

//         cout<<i<<":";

//         for (p=record[i]; p!=NULL; p=p->next)

//            cout<<"["<<p->in<<","<<p->out<<"], ";

//         cout<<endl;

//     }

 

       for (cin>>q; q>0; --q) {

           cin>>ts>>te>>ms;

           for (p=record[ms], t=0; p!=NULL; p=p->next) {

              if (p->in <= ts)

                  ls=ts;

              else

                  ls=p->in;

 

              if (p->out >= te)

                  le=te;

              else

                  le=p->out;

 

              if (le>ls) {

                  t+=(le-ls);

              //  cout<<le-ls<<endl;

              }

           }

           cout<<t<<endl;

       }

    }

 

    return 0;

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值