总结就是T3想错直接翻车233.
T1
第二题
【题目描述】
给你两个日期,问这两个日期差了多少毫秒。
【输入格式】
两行,每行一个日期,日期格式保证为“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 世纪的某一天,且第二个日期一定
大于等于第一个日期。
输出毫秒是为了坑答案等于零时,应该输出”0”而不是”0000”233,做过的应该都明白啥意思。
比较简单的模拟,考试的时候打的有点傻233,直接上代码
代码如下
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define ll long long
using namespace std;
int read()
{
int x = 0 , f = 1;
char in = getchar();
while(in < '0' || in > '9')
{
if(in == '-')
f = -1;
in = getchar();
}
while('0' <= in && in <= '9')
{
x = (x << 3) + (x << 1) + in - '0';
in = getchar();
}
return x * f;
}
char start_time[51] , end_time[51];
int month_len[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
int c_y,c_M,c_d,c_h,c_m,c_s;
int s_y,s_M,s_d,s_h,s_m,s_s;
int e_y,e_M,e_d,e_h,e_m,e_s;
void tokiyao_taomalai()
{
scanf("%s",start_time);
for(int i = 0 ; i < 4 ; i ++)
s_y = s_y * 10 + start_time[i] - '0';
for(int i = 5 ; i < 7 ; i ++)
s_M = s_M * 10 + start_time[i] - '0';
for(int i = 8 ; i < 10 ; i ++)
s_d = s_d * 10 + start_time[i] - '0';
memset(start_time,0,sizeof(start_time));
scanf("%s",start_time);
for(int i = 0 ; i < 2 ; i ++)
s_h = s_h * 10 + start_time[i] - '0';
for(int i = 3 ; i < 5 ; i ++)
s_m = s_m * 10 + start_time[i] - '0';
for(int i = 6 ; i < 8 ; i ++)
s_s = s_s * 10 + start_time[i] - '0';
scanf("%s",end_time);
for(int i = 0 ; i < 4 ; i ++)
e_y = e_y * 10 + end_time[i] - '0';
for(int i = 5 ; i < 7 ; i ++)
e_M = e_M * 10 + end_time[i] - '0';
for(int i = 8 ; i < 10 ; i ++)
e_d = e_d * 10 + end_time[i] - '0';
memset(end_time,0,sizeof(end_time));
scanf("%s",end_time);
for(int i = 0 ; i < 2 ; i ++)
e_h = e_h * 10 + end_time[i] - '0';
for(int i = 3 ; i < 5 ; i ++)
e_m = e_m * 10 + end_time[i] - '0';
for(int i = 6 ; i < 8 ; i ++)
e_s = e_s * 10 + end_time[i] - '0';
}
bool is(int x)
{
if(x % 400 == 0)
return true;
if(x % 100 != 0 && x % 4 == 0)
return true;
return false;
}
bool check(int e_y,int e_M,int e_d,int e_h,int e_m,int e_s)
{
if(c_y != e_y)
return false;
if(c_M != e_M)
return false;
if(c_d != e_d)
return false;
if(c_h != e_h)
return false;
if(c_m != e_m)
return false;
if(c_s != e_s)
return false;
return true;
}
ll calc(int e_y,int e_M,int e_d,int e_h,int e_m,int e_s)
{
ll ans = 0;
c_y = 2000 , c_M = 1 , c_d = 1 , c_h = 0 , c_m = 0 , c_s = 0;
month_len[2] = 28;
if(c_M < e_M)
while(c_y < e_y)
{
if(is(c_y))
ans += 366 * 24 * 3600;
else
ans += 365 * 24 * 3600;
c_y ++;
}
else
while(c_y < e_y - 1)
{
if(is(c_y))
ans += 366 * 24 * 3600;
else
ans += 365 * 24 * 3600;
c_y ++;
}
if(is(c_y))
month_len[2] ++;
if(c_d < e_d)
while(c_M < e_M)
{
ans += month_len[c_M] * 24 * 3600;
c_M ++;
}
else
while(c_M < e_M - 1)
{
ans += month_len[c_M] * 24 * 3600;
c_M ++;
}
if(is(c_y))
month_len[2] --;
if(c_h < e_h)
while(c_d < e_d)
{
ans += 24 * 3600;
c_d ++;
}
else
while(c_d < e_d - 1)
{
ans += 24 * 3600;
c_d ++;
}
if(c_m < e_m)
while(c_h < e_h)
{
ans += 3600;
c_h ++;
}
else
while(c_h < e_h - 1)
{
ans += 3600;
c_h ++;
}
if(c_s < e_s)
while(c_m < e_m)
{
ans += 60;
c_m ++;
}
else
while(c_m < e_m - 1)
{
ans += 60;
c_m ++;
}
bool flag = 0;
if(is(c_y))
month_len[2] ++ , flag = 1;
while(!check(e_y,e_M,e_d,e_h,e_m,e_s))
{
c_s ++;
ans ++;
if(c_s == 60)
c_s = 0 , c_m ++;
if(c_m == 60)
c_m = 0 , c_h ++;
if(c_h == 24)
c_h = 0 , c_d ++;
if(c_d == month_len[c_M]+1)
c_d = 1 , c_M ++;
if(c_M == 13)
{
c_M = 1 , c_y ++;
if(flag)
month_len[2] --;
else if(is(c_y))
month_len[2] ++;
}
}
return ans;
}
int main()
{
freopen("two.in","r",stdin);
freopen("two.out","w",stdout);
tokiyao_taomalai();
ll ans1 = calc(s_y,s_M,s_d,s_h,s_m,s_s);
ll ans2 = calc(e_y,e_M,e_d,e_h,e_m,e_s);
ll ans = ans2 - ans1;
if(ans)
printf("%lld000\n",ans);
else
puts("0");
fclose(stdin);
fclose(stdout);
return 0;
}
T2
死亡
【问题描述】
现在有M个位置可以打 sif ,有N + 1个人在排队等着打 sif 。现在告诉你前N个人每个人需要多长的时间打 sif ,问你第N + 1个人什么时候才能打 sif。 (前N个人必须按照顺序来)
【输入格式】
第一行两个整数N,M如上所述。
接下来N行每行一个整数代表每个人所需要用的时间。
【输出格式】
一行一个整数表示答案。
【样例输入】
3 2
1
1
1
【样例输出】
1
【样例解释】
山里有座庙。
【数据规模与约定】
对于100%的数据,每个人所需用的时间不超过10^5。
sx题,拿堆搞一搞完事儿,第 N + 1 push是第 N + 1 个人的最短时间。
代码如下
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define ll long long
using namespace std;
const int sz = 200100;
int read()
{
int x = 0 , f = 1;
char in = getchar();
while(in < '0' || in > '9')
{
if(in == '-')
f = -1;
in = getchar();
}
while('0' <= in && in <= '9')
{
x = (x << 3) + (x << 1) + in - '0';
in = getchar();
}
return x * f;
}
int n,m;
priority_queue < ll > q;
int num[sz];
int main()
{
freopen("death.in","r",stdin);
freopen("death.out","w",stdout);
n = read() , m = read();
for(int i = 1 ; i <= n ; i ++)
num[i] = read();
if(n < m)
puts("0");
else
{
for(int i = 1 ; i <= m ; i ++)
q.push(-num[i]);
for(int i = m + 1 ; i <= n ; i ++)
{
ll f = - q.top();
q.pop();
f += num[i];
q.push(-f);
}
printf("%lld\n",-q.top());
}
fclose(stdin);
fclose(stdout);
return 0;
}
/*
5 2
1 2 3 4 5
*/
T3
凝视
【问题描述】
背包是个好东西,希望我也有。
给你一个二维的背包,它的体积是N × M。现在你有一些大小为1×2和1×3的物品,每个物品有自己的价值。你希望往背包里面装一些物品,使得它们的价值和最大,问最大的价值和是多少。
【输入格式】
第一行一个整数��代表该测试点的数据组数。
对于每组数据,第一行有四个整数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!(瞎说别当真233),每个物品的体积一定,价值不同,所以对于每一类物品,优先拿价值高的正确性显然,然后就是怎么放的问题,思考直接放1 x 3的物品,每个紧挨着放一定可以放到只剩两个或一个空,1 x 2的物品同理,那么就不用考虑怎么放了,直接还能放就放就没问题,然后枚举下分给1 x 2物品的空间,处理下前缀和,计算下就好,这里需要注意的是,存在用完所有物品都不能把空间填满的数据(md还不少,其实跟n1,n2取下min就好了),于是就挂了233.
代码如下
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define ll long long
using namespace std;
ll read()
{
ll x = 0 , f = 1;
char in = getchar();
while(in < '0' || in > '9')
{
if(in == '-')
f = -1;
in = getchar();
}
while('0' <= in && in <= '9')
{
x = x * 10 + in - '0';
in = getchar();
}
return x * f;
}
int t;
ll s_sz[10010] , b_sz[10010];
ll sum_s_sz[10010] , sum_b_sz[10010];
bool cmp(int a,int b)
{
return a > b;
}
void init()
{
memset(s_sz,0,sizeof(s_sz));
memset(b_sz,0,sizeof(b_sz));
}
int main()
{
freopen("eyesight.in","r",stdin);
freopen("eyesight.out","w",stdout);
t = read();
while(t --)
{
ll ans = 0;
int n = read() , m = read() , n1 = read() , n2 = read();
init();
for(int i = 1 ; i <= n1 ; i ++)
s_sz[i] = read();
for(int i = 1 ; i <= n2 ; i ++)
b_sz[i] = read();
sort(s_sz+1,s_sz+n1+1,cmp);
sort(b_sz+1,b_sz+n2+1,cmp);
for(int i = 1 ; i <= n1 ; i ++)
sum_s_sz[i] = sum_s_sz[i-1] + s_sz[i];
for(int i = 1 ; i <= n2 ; i ++)
sum_b_sz[i] = sum_b_sz[i-1] + b_sz[i];
for(int S = 1 ; S <= n*m ; S ++)
ans = max(ans,sum_s_sz[min(S/2,n1)]+sum_b_sz[(min((n*m-S)/3,n2))]);
printf("%lld\n",ans);
}
fclose(stdin);
fclose(stdout);
return 0;
}