Problem 1 :第二题
【题目描述】
给你两个日期,问这两个日期差了多少毫秒。
【输入格式】
两行,每行一个日期,日期格式保证为“YYYY-MM-DD hh:mm:ss”这种形式。第二个日期时间一定比第一个日期时间要大两个日期的年份一定都是 21 世纪的年份。
【输出格式】
一行一个整数代表毫秒数。
【样例输入 1】
2000-01-01 00:00:00
2000-01-01 00:00:01
【样例输出 1】
1000
【样例输入 2】
2000-01-01 00:00:00
2000-11-11 00:00:00
【样例输出 2】
27216000000
【样例解释】
从前有座山。
【数据范围与规定】
对于10%的数据, 两个日期相同。
对于20%的数据,两个日期只有秒数可能不同。
对于30%的数据,两个日期只有秒数、分钟数可能不同。
对于40%的数据,两个日期的年月日一定相同。
对于60%的数据,两个日期的年月一定相同。
对于80%的数据,两个日期的年份一定相同。
对于100%的数据,两个日期一定都是 21 世纪的某一天,且第二个日期一定
大于等于第一个日期。
【思路】
依次计算由秒到小时差值,不足则向上借位,将秒,分,小时和年,月差值的影响转化为天数统一计算。注意判断闰年,若为闰年则二月增加一天。
代码是考场代码为了防止出错将60%/80%/100%分开写了有些繁琐。
【代码】
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef unsigned long long ll;
ll ns,ys,rs,ss,fs,ms,nz,yz,rz,sz,fz,mz;
ll ans;//最终答案
ll tmp;//完整月天数
ll tot;//区间闰年个数
ll trp;//年天数
ll siz[]={0,31,28,31,30,31,30,31,31,30,31,30,31};//月天数表
ll read()
{
char ch=getchar();
ll ret=0;
while(ch<'0'||ch>'9')
ch=getchar();
while(ch>='0'&&ch<='9')
{
ret=ret*10+(ch-'0');
ch=getchar();
}
return ret;
}
int main()
{
ns=read();ys=read();rs=read();ss=read();fs=read();ms=read();
nz=read();yz=read();rz=read();sz=read();fz=read();mz=read();
if(ns==nz&&ys==yz)//60%
{
if(mz>=ms)
ans+=(mz-ms)*1000;
else
{
fz--;//借位
mz+=60;
ans+=(mz-ms)*1000;
}
if(fz>=fs)
ans+=(fz-fs)*60*1000;
else
{
sz--;
fz+=60;
ans+=(fz-fs)*60*1000;
}
if(sz>=ss)
ans+=(sz-ss)*60*60*1000;
else
{
rz--;
sz+=24;
ans+=(sz-ss)*60*60*1000;
}
ans+=(rz-rs)*24*60*60*1000;//已经确定年月相同
}
else if(ns==nz&&ys!=yz)//80%
{
if(mz>=ms)
ans+=(mz-ms)*1000;
else
{
fz--;
mz+=60;
ans+=(mz-ms)*1000;
}
if(fz>=fs)
ans+=(fz-fs)*60*1000;
else
{
sz--;
fz+=60;
ans+=(fz-fs)*60*1000;
}
if(sz>=ss)
ans+=(sz-ss)*60*60*1000;
else
{
rz--;
sz+=24;
ans+=(sz-ss)*60*60*1000;
}
if(ns%4==0)//闰年
siz[2]++;
for(ll i=ys+1;i<=yz-1;i++)//完整月天数
tmp+=siz[i];
ans+=((siz[ys]-rs+tmp+rz)*24*60*60*1000);//转换为天数计算
}
else if(ns!=nz)//100%
{
if(mz>=ms)
ans+=(mz-ms)*1000;
else
{
fz--;
mz+=60;
ans+=(mz-ms)*1000;
}
if(fz>=fs)
ans+=(fz-fs)*60*1000;
else
{
sz--;
fz+=60;
ans+=(fz-fs)*60*1000;
}
if(sz>=ss)
ans+=(sz-ss)*60*60*1000;
else
{
rz--;
sz+=24;
ans+=(sz-ss)*60*60*1000;
}
for(ll i=ns+1;i<=nz-1;i++)//完整年天数
{
if(i%4==0)
tmp++;
tmp+=365;
}
if(ns%4==0&&ys<=2)//起始年份为闰年且差值范围包含2月
{
tmp++;
}
for(ll i=ys+1;i<=12;i++)//起始年份完整月天数
tmp+=siz[i];
tmp+=siz[ys]-rs;//当月剩余天数
if(nz%4==0&&yz>2)//终止年份为闰年且差值范围包含2月
tmp++;
for(ll i=1;i<=yz-1;i++)//终止年份完整月天数
tmp+=siz[i];
tmp+=rz;//当月包含的天数
ans+=tmp*24*60*60*1000;
}
printf("%llu",ans);
return 0;
}
Problem 2 :死亡
【问题描述】
现在有M个位置可以打 sif,有N + 1个人在排队等着打 sif。 现在告诉你前N个人每个人需要多长的时间打 sif,问你第N + 1个人什么时候才能打 sif。(前N个人必须按照顺序来)
【输入格式】
第一行两个整数N, M如上所述。
接下来N行每行一个整数代表每个人所需要用的时间。
【输出格式】
一行一个整数表示答案。
【样例输入】
3 2
1 1 1
【样例输出】
1
【样例解释】
山里有座庙。
【数据规模与约定】
对于100%的数据,每个人所需用的时间不超过105。
测试点 N M
1 10 10
2 20 10
3 50 10
4 1000 500
5 2000 500
6 5000 500
7 100000 5000
8 100000 10000
9 100000 20000
10 100000 50000
【思路】
我们发现加入都是有顺序的,那么我们记录每个人的结束时间(以前m个人开始时间为起点),即其等待时间+所需时间,放入优先队列中。每次取出结束时间最早的,将下一个人加入。等到n个人全部加入后再取出一个结束时间最早的,此时便是n+1个人的开始时间(一有空位立即补上无时间消耗)。
【代码】
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#define RI register int
using namespace std;
typedef long long ll;
ll n,m;
ll tim[200010];
ll ans,sum;//每个人可加入的时间,每个人打sif的结束时间
struct inin//好像不能直接改int的 <
{
ll t;//结束时间
};
priority_queue<inin>q;
bool operator < (inin a,inin b)
{
return a.t>b.t;
}
ll read()
{
char ch=getchar();
ll ret=0;
while(ch<'0'||ch>'9')
ch=getchar();
while(ch>='0'&&ch<='9')
{
ret=ret*10+(ch-'0');
ch=getchar();
}
return ret;
}
int main()
{
n=read();m=read();
inin tmp;
for(RI i=1;i<=n;i++)
{
tim[i]=read();
if(i<=m)
q.push((inin){tim[i]});
}
for(RI i=m+1;i<=n;i++)
{
tmp=q.top();
ans+=(tmp.t-ans);//ans=tmp.t队列中第一个结束时间即为将要加入人的开始时间
q.pop();
sum=ans+tim[i];
q.push((inin){sum});
}
tmp=q.top();
ans+=(tmp.t-ans);
printf("%lld",ans);
return 0;
}
Problem 3:凝视
【问题描述】
背包是个好东西,希望我也有。
给你一个二维的背包,它的体积是N × M。现在你有一些大小为1 × 2和1 ×
3的物品,每个物品有自己的价值。你希望往背包里面装一些物品,使得它们的
价值和最大,问最大的价值和是多少。
【输入格式】
第一行一个整数T代表该测试点的数据组数。
对于每组数据,第一行有四个整数N, M, n1, n2,其中n1, n2分别代表大小为
1 × 2和大小为1 × 3的物品个数。
接下来一行有n1个数代表每个1 × 2物品的价值。
接下来一行有n2个数代表每个1 × 3物品的价值。
【输出格式】
对于每组询问,输出能够达到的价值最大值。
【样例输入】
1
2 3 2 2
1 2
1 2
【样例输出】
4
【样例解释】
庙里有座山。
【数据规模与约定】
对于20%的数据, N, M ≤ 10, n1, n2 ≤ 100。
对于70%的数据, n, M ≤ 100,n1, n2 ≤ 2000。
对于100%的数据, 1 ≤ T ≤ 10,1 ≤ N, M ≤ 500,0 ≤ n1, n2 ≤ 10000。
【思路】
考试用数据比较水…背包DP可以60分2333
正解为贪心。