2022年3月双周赛(高级班)
最长连号
许多同学没拿满分的原因在于数组没开够,这道题数据范围明确说是不超过100000,然而很多同学只开到了10000,并且要注意因为数组比较大,只能用全局变量,使用局部变量会爆栈。或者这道题其实并不需要数组,用临时变量保存当前的数和前一个数即可。
示范代码采用数组写法,思路较简单,若a[i]=a[i-1]+1则sum++,若不等于则sum=1,若当前sum>ans即更新答案。
代码如下:
#include<bits/stdc++.h>
using namespace std;
int n,a[100010];
int sum=1,ans=1;
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=2;i<=n;i++)
{
if(a[i]==a[i-1]+1) sum++;
else sum=1;
if(sum>ans) ans=sum;
}
cout<<ans;
return 0;
}
谁拿了最多奖学金
这是一道较简单的模拟题,只要认真读题,理清逻辑,题目其实非常简单,主要考察读题的认真程度、对结构体及其排序的掌握。注意最后排序的时候若获得的奖学金相同,需要根据输入顺序排序。
代码如下:
#include<bits/stdc++.h>
using namespace std;
int all,n;
struct node
{
string s;
int sum,num;
}a[110];
bool cmp(node x,node y)
{
if(x.sum==y.sum) return x.num<y.num;
return x.sum>y.sum;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i].s;
a[i].num=i;
int x,y,z;
char q[2],w[2];
cin>>x>>y>>q>>w>>z;
if(x>80&&z>=1) a[i].sum+=8000;
if(x>85&&y>80) a[i].sum+=4000;
if(x>90) a[i].sum+=2000;
if(x>85&&w[0]=='Y') a[i].sum+=1000;
if(y>80&&q[0]=='Y') a[i].sum+=850;
all+=a[i].sum;
}
sort(a+1,a+1+n,cmp);
cout<<a[1].s<<endl<<a[1].sum<<endl<<all;
return 0;
}
前缀和
题库原题,主要思想正如题目名字,鉴于已有视频讲解,不再细说。需要注意的是许多同学失分在使用了cin/cout导致超时,对于输入输出数据比较多的题目尽量使用scanf/printf。
部分同学忘了前缀和的写法便直接放弃这道题,但这道题暴力方法十分显然,并且能得到绝大部分分数,在比赛时不应该放弃能得到的分。
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N=100010;
int a[N],sum[N];
int L[N],R[N];
int main()
{
int n,m,x;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
scanf("%d", &x);
sum[i]=x+sum[i-1];
}
for(int i=0;i<m;i++)
{
scanf("%d%d", &L[i], &R[i]);
}
for(int i=0; i<m; i++){
printf("%d\n", sum[R[i]]-sum[L[i]-1]);
}
return 0;
}
集合求和
首先需要明确集合的概念,集合一般被定义为:由一个或多个确定的元素所构成的整体。满足以下特性:
确定性:给定一个集合,任给一个元素,该元素或者属于或者不属于该集合,二者必居其一,不允许有模棱两可的情况出现。
互异性:一个集合中,任何两个元素都认为是不相同的,即每个元素只能出现一次。
无序性:一个集合中,每个元素的地位都是相同的,元素之间是无序的。
然后需要明确子集的概念:设S,T是两个集合,如果S的所有元素都属于T ,即称S是T的子集。空集是T的子集,T也是T的子集。
这道题就算不太明确上述概念,通过样例大家也能大概明确题目意思。看起来比较像递归,但其实可以用数学方法简单地做出来。
举个例子,假设有一个集合[1 2 3 4],子集包括[] [1] [2] [3] [4] [1 2] [1 3] [1 4] [2 3] [2 4] [3 4] [1 2 3] [1 2 4] [1 3 4] [2 3 4] [1 2 3 4],容易发现,其中每个数字出现的次数是相同的,都是8次,即2的3次方,再多举个例子我们很容易发现规律,答案为:元素和*2^(n-1) 。
严谨的数学推导如下:
代码如下(来自唐珞珈同学):
#include<bits/stdc++.h>
using namespace std;
int main() {
long long sum=0,g=0,a;
while(cin>>a){
sum+=a;
g++;
}
long long zjh=pow(2,g-1)*sum;
printf("%lld",zjh);
return 0;
}