第十周 限时模拟
Posted muxin2333
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第十周 限时模拟相关的知识,希望对你有一定的参考价值。
第一题:签到题
1.题意简介:TT有一个A×B×C的长方体。这个长方体是由A×B×C个1×1×1的小正方体组成的。
现在TT想给每个小正方体涂上颜色。
需要满以下三点条件:
(1)每个小正方体要么涂成红色,要么涂成蓝色。
(2)所有红色的小正方体组成一个长方体。
(3)所有蓝色的小正方体组成一个长方体。
现在TT想知道红色小正方体的数量和蓝色小正方体的数量的差异。
你需要找到红色正方体的数量与蓝色正方体的数量差值的绝对值的最小值。
即min{|红色正方体数量 - 蓝色正方体数量|}。
输入格式:输入仅一行,三个数A B C (2≤A,B,C≤10^9)。
要求输出:输出一个数字。
即差值绝对值的最小值。
2.思路分析:这道题的思路比较简单,由于是规则的方形,根据一些数学知识可以知道,把一个方体分成两个小方体,要想让它们的体积差最小,有两种情况:
(1)如果大方体中有一条边长为偶数,那么差值最小为0(即可以平均分)
(2)如果大方体中的长宽高都为奇数,那么差值最小为较小的两条边的乘积。
根据这个思路直接判断并计算即可。
3.代码:
#include <iostream> #include <algorithm> using namespace std; int main() { long long int cub[3]; for(int i=0;i<3;i++) cin>>cub[i]; if(cub[0]%2==0 || cub[1]%2==0 || cub[2]%2==0) { cout<<0<<endl; return 0; } else { sort(cub,cub+3); cout<<cub[0]*cub[1]<<endl; return 0; } }
第二题:团队聚会
1.题意简介:TA团队每周都会有很多任务,有的可以单独完成,有的则需要所有人聚到一起,开过会之后才能去做。但TA团队的每个成员都有各自的事情,找到所有人都有空的时间段并不是一件容易的事情。
给出每位助教的各项事情的时间表,你的任务是找出所有可以用来开会的时间段。
输入格式:
第一行一个数T(T≤100),表示数据组数。
对于每组数据,第一行一个数m(2 ≤ m ≤ 20),表示TA的数量。
对于每位TA,首先是一个数n(0≤ n≤100),表示该TA的任务数。接下来n行,表示各个任务的信息,格式如下
YYYY MM DD hh mm ss YYYY MM DD hh mm ss "some string here"
每一行描述的信息为:开始时间的年、月、日、时、分、秒;结束时间的年、月、日、时、分、秒,以及一些字符串,描述任务的信息。
数据约定:所有数据位数固定,描述信息的字符串可能有空格,但不超过100,所有的日期时间均在1800年1月1日00:00:00到2200年1月1日00:00:00之间。假定所有的月份(甚至2月)均是30天的。每件事务的结束时间点也即是该成员可以开始参与开会的时间点。
要求输出:
对于每一组数据,首先输出一行"Scenario #i:",i即表明是第i组数据。
接下来对于所有可以用来开会的时间段,每一个时间段输出一行。
需要满足如下规则:
在该时间段的任何时间点,都应该有至少两人在场。
在该时间段的任何时间点,至多有一位成员缺席。
该时间段的时间长度至少应该1h。
输出满足条件的所有的时间段,尽管某一段可能有400年那么长。
时间点的格式为MM/DD/YYYY hh:mm:ss。
时间段的输出格式为"appointment possible from T0 to T1",其中T0和T1均应满足时间点的格式。
严格按照格式进行匹配,如果长度不够则在前面补前导0。
按时间的先后顺序输出各个时间段。
如果没有合适的时间段,输出一行"no appointment possible"。
每组数据末尾须打印额外的一行空行。
2.思路分析:(有一说一,我本人是很不擅长做这类题目的,信息太多,处理比较麻烦,脑壳痛.jpg。(扶额))
首先来看这道题的主干,虽然给出的时间范围较广,时间也分为年月日小时分钟和秒,但是要求我们找出的是一个时间段,不需要进行太过于细致的时间操作,这里我利用一个gettime函数来进行时间的计算,根据题目要求的聚会时间判断一个时间段时间长度能否进行聚会。而说到时间段等数据段类型,就能自然想到用数组来帮助统计助教们的时间段。因此我选择利用vector<time> a;数组来帮助我解决这个问题。(这里的time为struct类型数据,里面封装了时间的相关信息)
从时间上来讲,我们首先要做的就是利用sort函数确定每个助教的时间段的先后顺序,确定好才能进行空闲时间段的挑选;顺序确定后,就可以进行时间段的统计了,一般来讲,如果统计的是助教的空闲时间,那么就会有非常多的情况,这样不利于时间段的存储和后续操作的进行,因此,这里统计出来的是一个时间点上忙碌的助教人数的一个数组。这样做的另外一个好处是在后面对空闲时间的选择时可以方便很多。进行空闲时间的选择时,思路为遍历整个忙碌人数的数组,只要一个时间点的忙碌人数大于2,就说明这个时间点不能进行聚会,即这个点为聚会时间的终点,然后这个终点和起点之间的时间段就是可以进行聚会的时间段。之后把起点定为这个终点的后一个时间点,继续进行遍历,依次得到所有的时间段即可。
3.代码:
#include <iostream> #include <stdio.h> #include <vector> #include <algorithm> #include <string> #include <string.h> using namespace std; int b[10000], d[10000]; struct time {//时间结构 int year,month,day,hour,minute,seconds;//记录时间 int count; time(){} bool operator <(const time& t) const{ if(year!=t.year) return year<t.year; else if(month!=t.month) return month<t.month; else if(day!=t.day) return day<t.day; else if(hour!=t.hour) return hour<t.hour; else if(minute!=t.minute) return minute<t.minute; else if(seconds!=t.seconds) return seconds<t.seconds; } bool operator==(const time & x) { if (year==x.year && month==x.month && day==x.day && hour==x.hour && minute==x.minute && seconds==x.seconds) return true; return false; } }; vector<time> a; int gettime(time l,time r) {//时间计算 if(r.year-l.year>=2) return true; r.month+=(r.year-l.year)*12; if(r.month-l.month>=2) return true; r.day+=(r.month-l.month)*30; if(r.day-l.day>=2) return true; r.hour+=(r.day-l.day)*24; if(r.hour-l.hour>=2) return true; r.minute+=(r.hour-l.hour)*60; r.seconds+=(r.minute-l.minute)*60; if(r.seconds-l.seconds>=3600) return 1; return 0; } int main() { int t, m, n, num; string s; time t1, t2; cin>>t; for(int i=0;i<t;i++) { int flag=0;//标记是否有空闲的时间 //初始化 memset(b, 0, sizeof(b)); memset(d, 0, sizeof(d)); cin>>n; int tot=0; for(int i=0;i<n;i++) { cin>>m; for(int i=0;i<m;i++) { cin>>t1.year>>t1.month>>t1.day>>t1.hour>>t1.minute>>t1.seconds; t1.count=tot++; cin>>t2.year>>t2.month>>t2.day>>t2.hour>>t2.minute>>t2.seconds; t2.count=tot++; getline(cin, s, ‘ ‘); if(t1==t2) { tot=tot-2; } else { a.push_back(t1); a.push_back(t2); } } } sort(a.begin(), a.end()); for(int i=0;i<a.size();i++) b[a[i].count] = i; for (int i=0;i<tot/2;i++) for (int j=b[i*2];j<b[i*2+1];j++) d[j]++; t1.year=1800,t1.month=t1.day=1,t1.hour=t1.minute=t1.seconds=t1.count=0; t2.year=2200,t2.month=t2.day=1,t2.hour=t2.minute=t2.seconds=t2.count=0; a.push_back(t2); d[tot]=10000; cout<<"Scenario #"<<i+1<<":"<<endl; num = 1; if(n==2) num = 0; for(int i=0;i<=tot;i++) { if(d[i]>num) { if(gettime(t1, a[i])) { flag=1; //保留最低两位,用printf printf("appointment possible from %02d/%02d/%02d %02d:%02d:%02d ", t1.month,t1.day,t1.year,t1.hour, t1.minute, t1.seconds); printf("to %02d/%02d/%02d %02d:%02d:%02d ", a[i].month, a[i].day, a[i].year, a[i].hour, a[i].minute, a[i].seconds); } t1 = a[i+1]; } } if(!flag) cout<<"no appointment possible"<<endl; cout<<endl;//空行 a.clear();//清空 } }
以上是关于第十周 限时模拟的主要内容,如果未能解决你的问题,请参考以下文章
2017-2018-2 20179215《网络攻防实践》第十周作业