H - Five Dishes
题意:很多菜,上菜只能在整点,做菜有时间,问如何最快上完菜。
思路:因为每个出菜必须整点,所以离整点远的时间会被卡的时间比较长,除了最后一道菜,之前的菜无论怎么换顺序,改卡的时间都省不掉,所以显然只需要让最后一次卡的时间多一些,这样中间的有效时间才可以短。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
typedef long long LL;
using namespace std;
const int N = 1e6+10;
LL a[N],b[N];
int main()
{
LL mi=0x3f3f3f3f3f;
LL k=1,n;
for(int i=1;i<=5;i++)
{
cin>>a[i];
int x=a[i]%10;
if(x!=0)
b[i]=10-x;
else b[i]=0;
if(x<mi&&x)
{
mi=x;
k=i;
}
}
LL sum=0;
for(int i=1;i<=5;i++)
{
if(i!=k)
sum=sum+a[i]+b[i];
}
sum+=a[k];
cout<<sum<<endl;
}
G - Five Antennas
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
typedef long long LL;
using namespace std;
const int N = 1e5+10;
int main()
{
LL a[10];
LL k;
for(int i=1;i<=5;i++) cin>>a[i];
cin>>k;
for(int i=1;i<=5;i++)
{
for(int j=i+1;j<=5;j++)
{
if(abs(a[i]-a[j])>k)
{
cout<<":("<<endl;
return 0;
}
}
}
cout<<"Yay!"<<endl;
}
I - Five Transportations
题意:六个城市,一号城市有 n 个人,每个城市之间有通道,通道每分钟最多可以过
a
i
a_i
ai 个人,没通过的人原地等候,问最终使得所有人到达第6个城市时,花费的最小时间。
思路:这道题一开始想以为是dp,结果发现每一个门槛高低不同,没法去状态转移。最后通过观察数据范围,感觉这道题枚举是不可能的,大概率是一道思维题,
O
(
1
)
O(1)
O(1)出解的那种,根据惯性去观察最值,如果门槛很大,那所有人都不会被卡住,5分钟可以完成通行,如果一个门槛很小,这样很多人都要挤在那个通道里等待,所以焦点就集中在这个最小值上了,想到这里就可以想到,每被卡一次要等一分钟,那么最后要卡大约
n
a
i
\dfrac{n}{a_i}
ain次,再加上来到最小值和最小值到第六个城之间的距离,也就是5次。如果
n
a
i
\dfrac{n}{a_i}
ain是整除,说明卡的最后一次没有意义,因为最后一次就走了,这里特殊考虑一下。
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
const int mod = 1e9+7;
typedef pair<int, int> PII;
typedef long long LL;
const int N = 1e5+10;
LL k[10];
int main()
{
LL n;
cin>>n;
LL mi=0x3f3f3f3f3f3f3f3f;
for(int i=1;i<=5;i++)
{
cin>>k[i];
if(k[i]<mi)
{
mi=k[i];
}
}
LL res;
if(n%mi==0)
res=n/mi+4;
else
{
res=n/mi+5;
}
cout<<res<<endl;
}
J - Cake 123
题意:题目给
x
,
y
,
z
,
k
x,y,z,k
x,y,z,k 如图,然后给了
A
,
B
,
C
A,B,C
A,B,C 三种序列 , 长度为
x
,
y
,
z
x,y,z
x,y,z,让你从三个序列里分别挑一个数,并得到这三个数的和,最后使得所有的和降序排列并输出前
k
k
k个。
思路:三个长度为1000的序列显然
n
3
n^3
n3超时,我想了好久这道题也想不出来做法。这道题首先要对前两个序列操作,贪心取出由前两个序列组成的降序和的前 k 个,这样的话k个元素可以保证都是前两个序列取出的最大的和了, 这时候再与第三个序列暴力枚举一下,把答案存到一个数组里。此时时间复杂度最大也只是
k
⋅
z
k·z
k⋅z,大概是
3
e
6
3e6
3e6左右,可以过。
#include <iostream>
#include <cstring>
#include <algorithm>
typedef long long LL;
using namespace std;
const int N = 3e6+10;
LL a[N],d[N];
LL c[N],b[N],ans[N];
bool cmp(LL a,LL b)
{
return a>b;
}
int main()
{
LL n,m,z,k;
cin>>n>>m>>z>>k;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=m;i++) cin>>b[i];
for(int i=1;i<=z;i++) cin>>c[i];
LL ct=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
d[++ct]=a[i]+b[j];
}
}
sort(d+1,d+1+ct,cmp);
ct=0;
for(int i=1;i<=k;i++)
{
for(int j=1;j<=z;j++)
{
ans[++ct]=d[i]+c[j];
}
}
sort(ans+1,ans+1+ct,cmp);
for(int i=1;i<=k;i++) cout<<ans[i]<<endl;
return 0;
}