一、初赛错题题解
第一题
题目
解析
选C。是一道送命题,会就会,不会就不会,平时多储备一些计算机基础知识,考到就是送分。
第二题
题目
解析
step1:将18个零件分成三堆,任选两堆比较一次。
有两种情况:
1° 如果有一对轻,那么那堆就是由次品(以下简称“次堆”)
2°如果比较的两堆不含次堆,即相等,那么没称的那堆是次堆。
以此类推,再过2次这样操作就可以确认次品了。
第三题
题目
解析
由365 % 7 = 1 , 366%7 = 2 可以得知,每过一个平年星期加一,每过一个闰年星期加二。
2021->2049 共28年 闰年有7年 ( 4 + 28 + 7 ) % 7 = 4
31 % 7 = 3 30 % 7 = 2 可以得知,每过大月星期假三,每过小月星期加二。
(4 + 3 + 3 + 2)% 7 = 5 结果是星期五,选B。
二、复赛错题解
第一题
题目
题解
最大的乘积值只可能在这两个数和这两个数的乘积中产生,所以统计 这四个数的最大值即可。
标程
#include<bits/stdc++.h>
using namespace std;
long long ans[4];
int main(){
//freopen("choose.in","r",stdin);
//freopen("choose.out","w",stdout);
long long a,b,c,d;
cin>>a>>b>>c>>d;
ans[0]=a*c;
ans[1]=a*d;
ans[2]=b*c;
ans[3]=b*d;
long long max_ans=-1e18;
for(int i=0;i<4;i++){
if(ans[i]>max_ans)
max_ans=ans[i];
}
cout<<max_ans;
}
第二题
题目
题解
首先,当 的时候,答案一定是 。
否则可以发现,其实「擦去之后填入新的」只是一个幌子,本质上是要求擦掉一个数之后其他所有数的最大公因数。设删去第 个数后其他所有数的最大公因数为 ,那么只要填入 的倍数就能保证公约数最大了。问题转变为:怎么求删去第 个数后的最大公因数是多少。分别记前缀后,例如,先 地递推一遍把 数组求出,然后擦除 后所有数字的最大公因数自然也就是 了。
这样就可以 地得到答案了。(思考:求 的过程是 的,其中 表示数值的大
小;那为何处理 数组时做 遍 却只有 的复杂度?)
标程
#include<bits/stdc++.h>
using namespace std;
const int maxN = 1e5 + 5;
int pre[maxN], suf[maxN],a[maxN],ans,n;
int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }
int main(){
cin >> n;
if (n == 1)
{
cout << int(1e9) << endl;
return 0;
}
for (int i = 1; i <= n; ++i)
cin >> a[i];
for (int i = 1; i <= n; ++i)
pre[i] = gcd(a[i], pre[i - 1]);
for (int i = n; i; --i)
suf[i] = gcd(a[i], suf[i + 1]);
int ans = 0;
for (int i = 1; i <= n; ++i)
ans = max(ans, gcd(pre[i - 1], suf[i + 1]));
cout << ans << endl;
}