程序设计思维与实践 week10-大模拟

大模拟

A - 签到题

题目:

TT有一个A×B×C的长方体。这个长方体是由A×B×C个1×1×1的小正方体组成的。

现在TT想给每个小正方体涂上颜色。

需要满以下三点条件:

每个小正方体要么涂成红色,要么涂成蓝色。
所有红色的小正方体组成一个长方体。
所有蓝色的小正方体组成一个长方体。
现在TT想知道红色小正方体的数量和蓝色小正方体的数量的差异。

你需要找到红色正方体的数量与蓝色正方体的数量差值的绝对值的最小值。
即min{|红色正方体数量 - 蓝色正方体数量|}。

输入
输入仅一行,三个数A B C (2≤A,B,C≤10^9)。

输出
输出一个数字。
即差值绝对值的最小值。


思路:

签到题

三边只有有一个是偶数,就能平分。

当三边都是奇数的时候,挑小的两条边的乘积作为差值。


代码:
#include <iostream>
#include <algorithm>
using namespace std;

int a[10];

int main()
{
	for(int i=1;i<=3;i++)
		cin>>a[i];
	
	sort(a+1,a+4);
	if(a[1]%2==0||a[2]%2==0||a[3]%2==0)
		cout<<"0"<<"\n";
	else
	{
		int t=a[3];
		if(t%2==0)
			cout<<"0"<<"\n";
		else
		{
			long long tmp=(long long)a[1]*a[2];
			cout<<tmp<<"\n";
		}
	}
	return 0;
}

B - 团队聚会

题目:

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”
每一行描述的信息为:开始时间的年、月、日、时、分、秒;结束时间的年、月、日、时、分、秒,以及一些字符串,描述任务的信息。

数据约定:
所有的数据信息均为固定位数,位数不足的在在前面补前导0,数据之间由空格隔开。
描述信息的字符串中间可能包含空格,且总长度不超过100。
所有的日期时间均在1800年1月1日00:00:00到2200年1月1日00:00:00之间。
为了简化问题,我们假定所有的月份(甚至2月)均是30天的,数据保证不含有不合法的日期。
注意每件事务的结束时间点也即是该成员可以开始参与开会的时间点。

输出
对于每一组数据,首先输出一行"Scenario #i:",i即表明是第i组数据。
接下来对于所有可以用来开会的时间段,每一个时间段输出一行。
需要满足如下规则:

在该时间段的任何时间点,都应该有至少两人在场。
在该时间段的任何时间点,至多有一位成员缺席。
该时间段的时间长度至少应该1h。
所有的成员都乐意一天24h进行工作。
举个例子,假如现在TA团队有3位成员,TT、zjm、hrz。那么这样的时间段是合法的:会议开始之初只有TT和zjm,后来hrz加入了,hrz加入之后TT离开了,此后直到会议结束,hrz和zjm一直在场。

要求:
输出满足条件的所有的时间段,尽管某一段可能有400年那么长。
时间点的格式为MM/DD/YYYY hh:mm:ss。
时间段的输出格式为"appointment possible from T0 to T1",其中T0和T1均应满足时间点的格式。
严格按照格式进行匹配,如果长度不够则在前面补前导0。
按时间的先后顺序输出各个时间段。
如果没有合适的时间段,输出一行"no appointment possible"。
每组数据末尾须打印额外的一行空行。


思路:

滑动窗口

先把所有的时间点都记录下来,然后用类似滑动窗口,或者说尺取法,判断每一个时间段是否符合要求,如果符合就按要求输出。最后判断是否有符合时间段,如果没有就输出no appointment possible。


总结:

这道题思路是简单,但是处理起来又琐碎又麻烦。


代码:
#include <iostream>
#include <string>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
struct Time
{
    int year,month,day,hour,minute,second;
    
    Time(){}
    Time(int y,int m,int d,int h,int mm,int s)
	{
        year=y;
        month=m;
        day=d;
        hour=h;
        minute=mm;
        second=s;
    }
    bool operator < (const Time &t) const
    {
        if (year!=t.year)
			return year<t.year;
        if (month!=t.month)
			return month<t.month;
        if (day!=t.day)
			return day<t.day;
        if (hour!=t.hour)
			return hour<t.hour;
        if (minute!=t.minute)
			return minute<t.minute;
        return second<t.second;
    }
    bool operator>(const Time &t) const {return t<*this;}
 
    bool operator<=(const Time &t) const {return !(t<*this);}
 
    bool operator>=(const Time &t) const {return !(*this<t);}
 
    bool operator==(const Time &t) const {return !(t<*this||*this<t);}
	   
}t_start[30][200],t_end[30][200],t[5000];
Time start_time(1800,1,1,0,0,0),end_time(2200,1,1,0,0,0);
int T,m,idx,t_num[30];//每个TA的任务数量

bool check_left(int x)
{
    int num=0;
    for (int i=1;i<=m;i++) 
	{
        if(t_num[i]==0||(t[x]<t_start[i][1])||(t[x]>=t_end[i][t_num[i]]&&t[x]<end_time))
		{
            num++;
            continue;
		}
        for (int j=1;j<=t_num[i];j++) 
		{
            if (t[x]>=t_start[i][j]&&t[x]<t_end[i][j])
				break;
            if (j+1<=t_num[i]&&t[x]>=t_end[i][j]&&t[x]<t_start[i][j+1]) 
			{ 
				num++; 
				break; 
			}
        }
    }
    if (num>=2&&m-num<=1)
		return true;
    return false;
}
bool check_right(int x)
{
    int num=0;
    for (int i=1;i<=m;i++) 
	{
        if (t_num[i]==0||(t[x]<=t_start[i][1]&&t[x]>start_time)||t[x]>t_end[i][t_num[i]])
		{
            num++;
            continue;
		}
        if(t[x]==t_end[i][t_num[i]])
			continue;
        for (int j=1; j<=t_num[i];j++)
		{
            if (t[x]>t_start[i][j]&&t[x]<=t_end[i][j])
				break;
            if (j+1<= t_num[i]&&t[x]>t_end[i][j]&&t[x]<=t_start[i][j+1]) 
			{ 
				num++; 
				break; 
			}
        }
    }
    if(num>=2&&m-num<=1)
		return true;
    return false;
}
bool check_len(int l,int r)
{
    Time left=t[l],right=t[r];
    if(right.year>left.year+1)
		return true;
		
    right.month+=12*(right.year-left.year);
    
    if(right.month>left.month+1)
		return true;
		
    right.day+=30*(right.month-left.month);
    
    if(right.day>left.day+1)
		return true;
		
    right.hour+=24*(right.day-left.day);
    
    if(right.hour>left.hour+1)
		return true;
		
    right.minute+=60*(right.hour-left.hour);
    
    right.second+=60*(right.minute-left.minute);
    
    if(right.second-left.second>=3600)
		return true;
    return false;
}
void print(int l,int r)
{
	if (t[l].month<10)cout<<"0";
   		cout<<t[l].month<<"/";
   	if (t[l].day<10)cout<<"0";
        cout<<t[l].day<<"/"<<t[l].year<<" ";
    if (t[l].hour<10)cout<<"0";
        cout<<t[l].hour<<":";
    if (t[l].minute<10)cout<<"0";
        cout<<t[l].minute<<":";
    if (t[l].second<10)cout<<"0";
        cout<<t[l].second;
   cout<<" to ";
    if (t[r].month<10)cout<<"0";
        cout<<t[r].month<<"/";
    if (t[r].day<10)cout<<"0";
        cout<<t[r].day<<"/"<<t[r].year<<" ";
    if (t[r].hour<10)cout<<"0";
        cout<<t[r].hour<<":";
    if (t[r].minute<10)cout<<"0";
        cout<<t[r].minute<<":";
    if (t[r].second<10)cout<<"0";
        cout<<t[r].second<<endl;
}
int main()
{
    cin>>T;
    for (int k=1;k<=T;k++) 
	{
        bool flag=false;
        memset(t_num,0,sizeof t_num);
        memset(t_start,0,sizeof t_start);
        memset(t_end,0,sizeof t_end);
        memset(t,0,sizeof t);
        idx=0;
        t[++idx]=start_time;
        t[++idx]=end_time;
        cin>>m;//TA 人数
        for (int i=1;i<=m;i++)
		 {
            cin>>t_num[i];
            for (int j=1;j<=t_num[i];j++) 
			{
                cin>>t_start[i][j].year>>t_start[i][j].month>>t_start[i][j].day>>t_start[i][j].hour>>t_start[i][j].minute>>t_start[i][j].second;
                cin>>t_end[i][j].year>>t_end[i][j].month>>t_end[i][j].day>>t_end[i][j].hour>>t_end[i][j].minute>>t_end[i][j].second;
                t[++idx]=t_start[i][j];
                t[++idx]=t_end[i][j];
                string str;
				getline(cin,str);
            }
        }
        sort(t+1,t+1+idx);
        
        cout<<"Scenario #"<<k<<":\n";
        int l=1,r=1;
        while (l<=idx&&r<=idx) 
		{
            r++;
            if(r>idx)break;
            //尽量向右
            while (r<=idx&&check_right(r)) 
                r++;
            r--;
            if (check_len(l,r))
			{
            	flag=true;
           		cout<<"appointment possible from ";
           		print(l,r);
            }
            l=r+1;
            //尽量向左
            while (l<=idx&&!check_left(l))
                l++;
            r=l;
        }
        if(!flag)
			cout<<"no appointment possible\n";
        cout<<endl;
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值