今天我们主要来做此次考试的后两题。
第一题。
E. Leftover Recipes
问题陈述
你的冰箱里有NN种食材。我们将它们称为食材11到食材NN。你拥有Q_iQi克的第ii种食材。
你可以制作两种类型的菜肴。要制作一份A类菜肴,你需要每种食材ii (1 \leq i \leq N)(1≤i≤N) A_iAi克。要制作一份B类菜肴,你需要每种食材ii B_iBi克。每种类型的菜肴只能整数份地制作。
仅使用冰箱中的食材,你能制作的最大菜肴总份数是多少?
约束条件
- 1 \leq N \leq 101≤N≤10
- 1 \leq Q_i \leq 10^61≤Qi≤106
- 0 \leq A_i \leq 10^60≤Ai≤106,且至少存在一个ii使得A_i \geq 1Ai≥1
- 0 \leq B_i \leq 10^60≤Bi≤106,且至少存在一个ii使得B_i \geq 1Bi≥1
- 所有输入值均为整数。
输入
输入从标准输入中以如下格式给出:
NN
Q_1Q1 Q_2Q2 \dots… Q_NQN
A_1A1 A_2A2 \dots… A_NAN
B_1B1 B_2B2 \dots… B_NBN
输出
假设你可以制作的最大菜肴总数为SS份,请输出这个整数SS。
示例输入 1
2
800 300
100 100
200 10
示例输出 1
5
这个冰箱含有800800克的食材11和300300克的食材22。
你可以用100100克的食材11和100100克的食材22制作一份A类菜肴,或者用200200克的食材11和1010克的食材22制作一份B类菜肴。
为了制作两份A类菜肴和三份B类菜肴,你需要100 \times 2 + 200 \times 3 = 800100×2+200×3=800克的食材11,以及100 \times 2 + 10 \times 3 = 230100×2+10×3=230克的食材22,这些都不会超过冰箱中的可用量。这样,你可以总共制作五份菜肴,但无法制作六份,因此答案是55。
示例输入 2
2
800 300
100 0
0 10
示例输出 2
38
你可以用800800克的食材11制作88份A类菜肴,并用300300克的食材22制作3030份B类菜肴,总计3838份。
示例输入 3
2
800 300
801 300
800 301
示例输出 3
0
你无法制作任何菜肴。
示例输入 4
10
1000000 1000000 1000000 1000000 1000000 1000000 1000000 1000000 1000000 1000000
0 1 2 3 4 5 6 7 8 9
9 8 7 6 5 4 3 2 1 0
示例输出 4
222222
这道题当时我们考试的时候没有一个人做出来。
但是呢这道题其实可以这样做。
首先先求出这些能买a的数量的最大值。
然后再求出剩下的余数,看这个余数能买几分儿b。
然后呢把这个a的最大值每次减,然后呢因为这个a的最大值减,所以说呢他剩下的这些材料也会增加。
然后呢这时候呢再用现在的材料总数去找b,把他们两个的现在的值加起来,然后打一下擂台求最大值就好了。
代码如下,
#include<bits/stdc++.h>
using namespace std;
int n,q[15],a[15],b[15],aax=1e9,bax=1e9,ans=-1,a1;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>q[i];
}
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<=n;i++)
{
cin>>b[i];
}
for(int i=1;i<=n;i++)
{
if(a[i]!=0)
{
aax=min(aax,q[i]/a[i]);
}
}
for(int i=0;i<=aax;i++)
{
bax=1e9;
for(int j=1;j<=n;j++)
{
if(b[j]!=0)
{
bax=min(bax,q[j]/b[j]);
}
q[j]-=a[j];
}
ans=max(ans,i+bax);
}
cout<<ans;
return 0;
}
第二题
F. Even-Odd Increments
给定一个由 nn 个整数 a_1, a_2, \ldots, a_na1,a2,…,an 组成的数组。你需要处理 qq 个查询,查询分为两种类型:
- 类型为 "0 x_jxj" 的查询:将值 x_jxj 加到数组 aa 中的所有偶数元素上。
- 类型为 "1 x_jxj" 的查询:将值 x_jxj 加到数组 aa 中的所有奇数元素上。
请注意,在处理查询时,我们关注的是 a_iai 这个数字的奇偶,而不是它的下标或位置。
在处理每个查询后,输出数组 aa 中所有元素的和。
请注意,某些测试用例的答案可能不适合 32 位整数类型,因此你应该在你的编程语言中使用至少 64 位整数类型(例如 C++ 中的 long long
)。
输入格式
输入的第一行包含一个整数 tt (1 \leq t \leq 10^4)(1≤t≤104),表示测试用例的数量。
每个测试用例的描述如下:
- 第一行包含两个整数 nn 和 qq (1 \leq n, q \leq 10^51≤n,q≤105),分别表示数组 aa 的长度和查询的数量。
- 第二行包含 nn 个整数:a_1, a_2, \ldots, a_na1,a2,…,an (1 \leq a_i \leq 10^91≤ai≤109),表示数组 aa 的元素。
- 接下来的 qq 行包含查询,每个查询由两个整数 type_jtypej 和 x_jxj 组成 (0 \leq type_j \leq 10≤typej≤1, 1 \leq x_j \leq 10^41≤xj≤104)。
保证所有测试用例中 nn 的总和不超过 10^5105,qq 的总和也不超过 10^5105。
输出格式
对于每个测试用例,输出 qq 个数字,表示处理每个查询后数组 aa 中所有元素的和。
示例输入
输入数据 1
4
1 1
1
1 1
3 3
1 2 4
0 2
1 3
0 5
6 7
1 3 2 4 10 48
1 6
0 5
0 4
0 5
1 3
0 12
0 1
6 7
1000000000 1000000000 1000000000 11 15 17
0 17
1 10000
1 51
0 92
0 53
1 16
0 1
输出数据 1
2
11
14
29
80
100
100
100
118
190
196
3000000094
3000060094
3000060400
3000060952
3000061270
3000061366
3000061366
示例输出
提示
在第一个测试用例中,数组 aa 在第一个查询后变为 [2][2]。
在第三个测试用例中,数组 aa 的修改过程如下:[1, 3, 2, 4, 10, 48][1,3,2,4,10,48] \rightarrow→ [7, 9, 2, 4, 10, 48][7,9,2,4,10,48] \rightarrow→ [7, 9, 7, 9, 15, 53][7,9,7,9,15,53] \rightarrow→ [7, 9, 7, 9, 15, 53][7,9,7,9,15,53] \rightarrow→ [10, 12, 10, 12, 18, 56][10,12,10,12,18,56] \rightarrow→ [22, 24, 22, 24, 30, 68][22,24,22,24,30,68] \rightarrow→ [23, 25, 23, 25, 31, 69][23,25,23,25,31,69]。
这道题我在考试时的策略出了问题。
我一直在死磕前一道题,导致这道题也没做出来。
其实这道题是能做出来的。
就只要按他说的一步一步来就行了。
代码如下,
#include<bits/stdc++.h>
using namespace std;
long long t,n,q,a,b,s[1000000],sum1,sum2,sum;
int main(){
scanf("%lld",&t);
for(int g=1;g<=t;g++){
scanf("%lld%lld",&n,&q);
for(int i=1;i<=n;i++){
scanf("%lld",&s[i]);
if(s[i]%2==0)
sum2++;
else
sum1++;
sum+=s[i];
}
for(int i=1;i<=q;i++){
scanf("%lld%lld",&a,&b);
if(a==0){
sum+=sum2*b;
if(b%2!=0){
sum1+=sum2;
sum2=0;
}
}
else{
sum+=sum1*b;
if(b%2!=0){
sum2+=sum1;
sum1=0;
}
}
printf("%lld\n",sum);
}
sum=0;
sum1=0;
sum2=0;
}
return 0;
}
第三题课后作业。
V. B - 754 (AI)
问题陈述
有一个由数字 1
,2
,......,9
组成的字符串 SS。腊肠犬 Lunlun 会从 SS 中取出三个连续的数字,将它们视为一个整数 XX 并带给她的主人。(她不能重新排列这些数字。)
主人最喜欢的数字是 753753。越接近这个数字越好。XX 和 753753 之间的最小可能(绝对)差值是多少?
约束条件
- SS 是一个长度在 44 到 1010(含)之间的字符串。
- SS 中的每个字符都是
1
,2
,...... 或9
。
输入
通过标准输入以以下格式给出输入:
SS
输出
打印出 XX 和 753753 之间可能的最小差值。
样本输入 1
1234567876
样本输出 1
34
取出第七个到第九个字符得到的 X = 787X=787,与 753753 的差值为 787 - 753 = 34787−753=34。无论从哪里取出 XX,差值都不能更小。
注意不能重新排列数字。例如,取出 567
然后重新排列为 765
是不允许的。
也不能从 SS 中取出不连续的三个数字。例如,取出第七个数字 7
,第九个数字 7
和第十个数字 6
得到 776
是不允许的。
样本输入 2
35753
样本输出 2
0
如果可以取出 753
本身,答案就是 00。
样本输入 3
1111111111
样本输出 3
642
无论从哪里取出 XX,X = 111X=111,与 753753 的差值为 753 - 111 = 642753−111=642。
这道题我本来是没有什么思路甚,甚至想用三重for循环去解,但其实是这样的,我们可以用。每把它每每个数组合一下。再减去753就行了,再取最小值。
代码如下,
#include<bits/stdc++.h>
using namespace std;
string s;
int a,b,c,d,minn=99999999;
int main()
{
cin>>s;
for(int i=0;i<s.size();i++)
{
a=((s[i]-'0')*100)+((s[i+1]-'0')*10)+s[i+2]-'0';
b=abs(a-753);
minn=min(minn,b);
}
cout<<minn;
return 0;
}