2020-2021年度第二届全国大学生算法设计与编程挑战赛(春季赛)部分题题解
Posted 辉小歌
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2020-2021年度第二届全国大学生算法设计与编程挑战赛(春季赛)部分题题解相关的知识,希望对你有一定的参考价值。
2021年6月份打的比赛,现在才开始复盘。
目录
A: 智慧果【难度: 签到题 / 知识点: 递推】
http://106.75.49.226/problem/ADPC1-Z-A
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
const int mod=1e5;
long long int f[N],n;
int main(void)
{
f[1]=1,f[2]=2,f[3]=5;
for(int i=4;i<=1000;i++) f[i]=(f[i-1]*f[i-2]*f[i-3]+f[i-1]+f[i-2]+f[i-3])%mod;
cout<<f[1000];
return 0;
}
B: Xanadu【难度: 中 / 知识点: 最短路】
http://106.75.49.226/problem/ADPC1-Z-B
通过每一行的点,它前面有几个1就要走多远。以此来建立一个图,对于该图求最短路即可。
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10;
const int inf=0x3f3f3f3f;
int g[N][N],dist[N],st[N],n,cnt;
int a[N][N];
int Dijkstra()
{
memset(dist,0x3f,sizeof dist);
dist[1]=0;
for(int i=0;i<n;i++)
{
int t=-1;
for(int j=1;j<=n;j++) if(!st[j]&&(t==-1 || dist[j]<dist[t] )) t=j;
st[t]=1;
for(int j=1;j<=n;j++) dist[j]=min(dist[j],dist[t]+g[t][j]);
}
return dist[n];
}
int main(void)
{
cin>>n;
memset(g,0x3f,sizeof g);
for(int i=1;i<=n;i++)
{
int t=0;
for(int j=1;j<=n;j++)
{
cin>>a[i][j];
if(a[i][j]) g[i][j]=t,t++;
}
}
int ans=Dijkstra();
cout<<ans<<endl;
return 0;
}
C: 这是一道大难题【难度: 一般 / 知识点: 最小生成树】
http://106.75.49.226/problem/ADPC1-Z-C
解析: 先将选的边连接,再跑一下克鲁斯卡尔算法即可。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*2+10;
struct edge{int a,b,c;}edges[N];
int n,m,k,cnt,p[N];
long long int res;
int find(int x)
{
if(x!=p[x]) p[x]=find(p[x]);
return p[x];
}
bool cmp(edge a,edge b) {return a.c<b.c;}
void kruskal()
{
for(int i=1;i<=n;i++) p[i]=i;
res+=edges[k-1].c;
p[find(edges[k-1].b)]=find(edges[k-1].a);
cnt++;
sort(edges,edges+m,cmp);
for(int i=0;i<m;i++)
{
int a=edges[i].a,b=edges[i].b,c=edges[i].c;
if(find(a)!=find(b))
{
res+=c;
p[find(b)]=find(a);
cnt++;
}
}
}
int main(void)
{
cin>>n>>m;
for(int i=0;i<m;i++) cin>>edges[i].a>>edges[i].b>>edges[i].c;
cin>>k;
kruskal();
cout<<res;
return 0;
}
H: 智慧数【难度: 签到 / 知识点: 模拟】
http://106.75.49.226/problem/ACPC1-Z-H
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
LL cnt;
int main(void)
{
for(LL i=2;;i++)
{
for(LL j=2;j<i;j++)
{
if(i%j==0)
{
LL t=sqrt(i*j);
if(t*t==i*j)
{
cnt++;
if(cnt==3000)
{
cout<<i<<endl;
return 0;
}
break;
}
}
}
}
return 0;
}
L: 这是一道压轴题【难度: 一般 / 知识点: 思维 枚举】
http://106.75.49.226/problem/ADPC1-Z-L
解析: 将一串的0和1压缩为一个数,最后枚举中间去掉的一段。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,k,ans;
vector<int>ve;
string s;
int main(void)
{
cin>>n; cin>>s;
for(int i=0;i<n;i++)
{
k++;
if((i+1==n) || s[i]!=s[i+1] ) ve.push_back(k),ans=max(ans,k),k=0;
}
for(int i=1;i<ve.size();i++)
{
if(i!=ve.size()-1) ans=max(ans,ve[i-1]+ve[i+1]);
}
cout<<ans<<endl;
return 0;
}
以上是关于2020-2021年度第二届全国大学生算法设计与编程挑战赛(春季赛)部分题题解的主要内容,如果未能解决你的问题,请参考以下文章
2020-2021年度第二届全国大学生算法设计与编程挑战赛(冬季赛)——正式赛
2020-2021年度第二届全国大学生算法设计与编程挑战赛 (春季赛)- 天才的操作(线段树+主席树+树上倍增)
个人赛组2021-2022年度第三届全国大学生算法设计与编程挑战赛(秋季赛)-正式赛
个人赛组2021-2022年度第三届全国大学生算法设计与编程挑战赛(秋季赛)——热身赛