Week10 团队聚会

Week10 团队聚会

 

 

 

 

 

 

 

 

 

 

思路分析:

  本题是一道大模拟题,首先我们要考虑数据的格式转化问题,这题我将所有的时间都转化成秒钟,然后创建节点类,记录记录会议的起始时间和结束时间,然后我们都如每一个助教的数据,按照string 读入抛弃掉无关数据,然后时候sort排序,一次对每个节点检查,记录满足要求的时间段。

  要注意时间转化一定要用long long数据类型。 

代码如下:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#define ll long long
using namespace std; 
const int maxn=2010;
int T, m, n, Tot,Size;bool flag; ll B,E;//给定起终点  
struct TIME{
    ll L,R;
    bool operator<(TIME p){
      if(L!=p.L) return L<p.L;
      else return R<p.R;
    }
}noMeets[maxn];    vector<ll> Table;       //时间段, 时间点 
TIME create(ll l,ll r){
    TIME p;p.L=l;p.R=r; return p;
}
ll timetoll(ll Y,ll M,ll D,ll h,ll m,ll s){                   //时间转换成long long数 
    ll len=((Y-1800)*12 + M-1)*30+D-1;
    len=((len*24+h)*60+m)*60 + s; return len;
}
void lltotime(ll t){                                         //long long型数打印成格式时间 
    ll Y,M,D,h,m,s;
    s=t%60; t/=60;    m=t%60; t/=60;   h=t%24;t/=24;   D=t%30 +1;t/=30;   M=t%12+1;t/=12;   Y=t+1800;
    if(M<10) { printf("0"); }  printf("%d/",M);  if(D<10) { printf("0"); }  printf("%d/",D);
    printf("%d ",Y);                             if(h<10) { printf("0"); }  printf("%d:",h);
    if(m<10) { printf("0"); }  printf("%d:",m);  if(s<10) { printf("0"); }  printf("%d",s);  
}
void init(){ //初始化 
    Size=0;Tot=0; flag=false;  Table.clear(); B= timetoll(1800,1,1,0,0,0); E= timetoll(2200,1,1,0,0,0); Table.push_back(B);Table.push_back(E);
}
void strtotime(string s){//字符转换成时间 
      int len=s.size(); int TIM[12],t=-1,cnt=0;
      for(int i=0;i<len;++i){
          if(s[i]<'0'||s[i]>'9'){
           TIM[++t]=cnt;cnt=0;if(t==11) break;
        } else cnt=cnt*10 + (s[i]-'0');     
    } 
    ll b=timetoll(TIM[0],TIM[1],TIM[2],TIM[3],TIM[4],TIM[5]),e=timetoll(TIM[6],TIM[7],TIM[8],TIM[9],TIM[10],TIM[11]);
    noMeets[Size++]=create(b,e); Table.push_back(b);Table.push_back(e);
}
bool checkL(int L){
    if(L>=Tot-1) return false;
    ll p=Table[L]; int cnt=0;
    for(int i=0;i<Size;++i){
        if(noMeets[i].L<=p){
            if(noMeets[i].R>p) ++cnt;
            else continue;
        }
        else break;
    }
    if(cnt<2 && (m-cnt)>1) return true;
    else return false;
}
bool checkR(int R){
    if(R>Tot-1) return false;
    ll p=Table[R]; int cnt=0;
    for(int i=0;i<Size;++i){
        if(noMeets[i].L<p){
            if(noMeets[i].R>=p) ++cnt;
            else continue;
        }
        else break;
    }
    if(cnt<2 && (m-cnt)>1) return true;
    else return false;    
}
bool checklen(ll p1,ll p2){
    if((p2-p1)>=3600 )return true;
    else return false;
}
void checkTIM(int L,int R){
    ll p1=Table[L],p2=Table[R];
    if(!checklen(p1,p2)) return;  flag=true;
    printf("appointment possible from "); lltotime(p1);
    printf(" to "); lltotime(p2); printf("\n");
}
void Solve(int t){
  //数据处理
  sort(Table.begin(),Table.end());sort(noMeets,noMeets + Size);
  Table.erase(unique(Table.begin(),Table.end()),Table.end());
  Tot=Table.size(); printf("Scenario #%d:\n",t);
  //从给定起点遍历所有出现的时间点 
  int L=0,R=0;
  while(L<Tot && R<Tot){ 
    while(L<Tot && !checkL(L)) L++;    R=L+1;
    while(R<Tot && checkR(R))  R++;  R--;
    checkTIM(L,R);     L=R+1;
  }
  if(!flag) printf("no appointment possible\n");
  printf("\n");
}
int main(){
    scanf("%d",&T);string str;
    for(int i=1;i<=T;++i){
        scanf("%d",&m);    init();
        for(int j=0;j<m;++j){
            scanf("%d",&n);cin.ignore();
            for(int k=0;k<n;++k){
                getline(cin,str); strtotime(str);
            }
        }  Solve(i);
    }
    return 0;

} 
View Code

 

posted on 2020-06-10 11:29  FFchopin  阅读(164)  评论(0编辑  收藏  举报

导航