week10csp模拟测试

问题B - 团 队 聚 会 (不支持C++11)

问题描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

题目分析

主要利用了重载<符号,和c++的stl函数,set函数。
1.建立结构体,由于400年直接转换成秒来储存的话有些困难,就还是按照年月日小时分钟秒来储存的。
然后重载了小于符号,将时间的比较大小快速实现。
2.建立table的结构体,用于表示一段时间的开始和结尾。
3.ta的任务用vector的结构体表示。将每一次任务的开始和结尾的时间都插入一个vector中,可能就是一段会议能够开始的时间。
4.拿出那些可以用来开会的时间挨个和每个助教的时间做对比,如果助教有在那个时间里有任务,那么就表示这个助教没法在那段时间加入会议。计算那个时间段里能够参加的助教数目,看是否能够展开会议。能的话就把这个时间记录下来。即可。

代码
#include<stdio.h>
#include<vector>
#include<set>
using namespace  std;
#define ll long long
struct Time
{
	int Y,M,D,h,m,s;
	Time(int _Y,int _M,int _D,int _h,int _m,int _s)
		:Y(_Y),M(_M),D(_D),h(_h),m(_m),s(_s){ }
	Time(int *t)
	{
		Y=t[0];
		M=t[1];
		D=t[2];
		h=t[3];
		m=t[4];
		s=t[5];
	}
	bool operator<(const Time& t) const
	{
		if(Y!=t.Y) return Y<t.Y;
		if(M!=t.M) return M<t.M;
		if(D!=t.D) return D<t.D;
		if(h!=t.h) return h<t.h;
		if(m!=t.m) return m<t.m;
		return s<t.s;
	}
	bool operator<=(const Time& t) const
	{
		return !(t<*this);
	}
	bool operator>=(const Time& t) const
	{
		return !(*this<t);
	}
};

struct Table
{
	Time s;
	Time e;
	Table(Time _s,Time _e):s(_s),e(_e){	}
 } ;
 int m;
set<Time> time_set;
vector<Time> time_point;
vector<Table> ta[25],ans;

bool isNotBusy(int i,Time s,Time e)
{
	for(int j = 0; j < ta[i].size(); j++){
		Table t = ta[i][j];
		if(t.s <= s && t.e >= e) return false;
		// 不可能有一个t,t.s>s&&t.e<e 因为s,e都是time_set里紧挨着的 
	}
	return true;
}

bool isOk(Time s, Time e){
	int cnt = 0;
	for(int i = 1; i <= m; ++i){  // 对每一个TA进行判断,是否可以开会 
		if(isNotBusy(i, s, e)) cnt++;
	}
	if(cnt >= 2 && cnt >= m-1) return true;
	return false;
}
bool isOver1h(Time s, Time e){
	ll st = (((((1ll*s.Y-1800)*12+s.M-1)*30+s.D-1)*24+s.h)*60+s.m)*60+s.s;
	ll et = (((((1ll*e.Y-1800)*12+e.M-1)*30+e.D-1)*24+e.h)*60+e.m)*60+e.s;
	if(et - st >= 3600) return true;
	return false;
} 
int main()
{
	int t;
	scanf("%d",&t);
	Time ss(1800,1,1,0,0,0),ee(2200,1,1,0,0,0);
	for(int t1=1;t1<=t;t1++)
	{
		scanf("%d",&m);
		for(int i=1;i<=m;i++)
		{
			ta[i].clear();
		}
		ans.clear();
		time_set.clear();
		time_point.clear();
		time_set.insert(ss);
		time_set.insert(ee);
		for(int i=1;i<=m;i++)
		{
			int n;
			scanf("%d",&n);
			for(int j=1;j<=n;j++)
			{
				int start[6],end[6];
				for(int k=0;k<6;k++) scanf("%d",&start[k]);
				for(int k=0;k<6;k++) scanf("%d",&end[k]);
				char info[105];
				scanf("%[^\n]",&info);
				Time s=Time(start),e=Time(end);
				time_set.insert(s);
				time_set.insert(e);
				ta[i].push_back(Table(s,e));
				
				
			}
		 }
		for(set<Time>::iterator i = time_set.begin(); i != time_set.end(); i++)
		{
			// ans的所有可能都在端点上  set已经排好序 可以按序便历 
			time_point.push_back(*i);
		}
		int le=0,ri=0,len=time_point.size();
		while(ri<len)
		{
			while(ri<len-1&&isOk(time_point[ri],time_point[ri+1])) ri++;
			if(isOver1h(time_point[le],time_point[ri]))
				ans.push_back(Table(time_point[le],time_point[ri]));
			le=ri+1;
			while(le<len-1&&(!isOk(time_point[le],time_point[le+1])))le++;
			ri=le+1;
		}
		
		printf("Scenario #%d:\n", t1);
		if(ans.size() == 0){
			printf("no appointment possible\n");
		}else{
			for(int i = 0; i < ans.size(); ++i){
				Time s = ans[i].s, e = ans[i].e;
				printf("appointment possible from %02d/%02d/%d %02d:%02d:%02d to %02d/%02d/%d %02d:%02d:%02d\n"
					, s.M, s.D, s.Y, s.h, s.m, s.s, e.M, e.D, e.Y, e.h, e.m, e.s);
			}
		}
		printf("\n");
	}
}
遇到的问题

1.时间的表达,化成秒太多
2.复杂度计算错误,以为会很复杂,没有考虑直接暴力寻找法来做这个题
3.巧用多个结构体,将时间表达出来。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值