深圳技术大学第二届软件和信息技术大赛-题解报告
作者:互联网
写在前面
这次比赛出题人有三位
钱贵宁EFI
周家宝BCGH
徐嘉辉ADJ
由于本次比赛主要目的是为了选拔蓝桥杯的预备参赛队员,所以赛制上选择了大家可能比较陌生的OI赛制,所有提交只有赛后一次结算机会。考虑很多人第一次接触这个赛制,我们的数据上给出了很多组很小的数据,基本保证就算全部用最基础的暴力方法,都可以完成除了后2个压轴题的所有分数。题目分为5个填空5个编程题,从难度上说,ABC考察了对基础语法和数据结构知识的了解,DE正解分别要用BFS和数论,前三个编程题都是语法层面的考察,I题考察了异或的灵活运用,处于友好set或sort的算法也也能拿到所有分数。压轴题暴力能拿4分或8分,正解是莫比乌斯反应。从得分分布来看,区分度也基本符合预期。如果有兴趣了解比赛中题目的正解,可以继续看下去
A土豆摸鱼
首先考虑闰年的数量算出天数,根据5和7的最小公倍数得出周期判断即可。
#include<stdio.h> int main(){ int a,b,c; a=365*10+3+31*3+30*2+10+23;//总共有3839天 b=a/35;// 5和7的最小公倍数是35;以35天为周期,每个周期满足条件的星期三有2天 ;共109个周期 c=a%35;//多出的24天内满足条件的星期三有2天; printf("%d",b*2+2); }
D黑白棋
这个题目正解要用状态压缩和BFS一起来解决问题。思路可以概括为广搜+map去重,map里存过程中的状态 ,用bfs遍历所有状态,得到需要的最短步数。这道题由于给出情况比较简单,观察后很容易直接输出来,不过正解代码还是发出来给大家参考。
#include<bits/stdc++.h> using namespace std; queue<string>q; string a,b; map<string,string>m; void yy(int i,string ss){//上下换 string sss=ss; char c; c=ss[i]; ss[i]=ss[i+4]; ss[i+4]=c; if(m.count(ss)==0){ q.push(ss); char aa=49+i/4,bb=49+i%4,cc=50+i/4,dd=49+i%4;//这里的横竖坐标都是从0开始的,存进去要加1 m[ss]=m[sss]+aa+bb+cc+dd; } return; } void xx(int i,string ss){//左右换 string sss=ss; char c; c=ss[i]; ss[i]=ss[i+1]; ss[i+1]=c; if(m.count(ss)==0){ q.push(ss); char aa=49+i/4,bb=49+i%4,cc=49+i/4,dd=50+i%4; m[ss]=m[sss]+aa+bb+cc+dd; } return; } //考虑四个方向会重复,所以只需考虑两个方向,这里是右和下。 void bfs(){ q.push(a); m[a]=""; while(q.empty()==false){ string ss=q.front(); for(int i=0;i<16;i++){ if(i<12){//不是最后一行就和下面换 yy(i,ss); } if(i%4!=3){//不是最后一列就和右边换 xx(i,ss); } } if(m.count(b)!=0){//出现目标序列 cout<<m[b].size()/4<<endl; for(int j=0;j<m[b].size();j++){ cout<<m[b][j]; if(j%4==3)cout<<endl;//每输出四个换一行 } return; } q.pop(); } return; } int main(){ for(int i=0;i<16;i++){ char c; cin>>c; a+=c; } for(int i=0;i<16;i++){ char c; cin>>c; b+=c; } bfs(); return 0; }
J我本来是签到题
这道题如果仅仅用暴力去解决只能通过1/6的数据点,稍加优化可以通过1/3.不过都不足以解决问题。
正确做法是我们先用c数组预处理出每个数出现的次数,那么原问题变为求解
其中n表示最大的数。然后莫比乌斯反演转化一下
代码就是莫比乌斯反演的基本板子
#include<bits/stdc++.h> using namespace std; #define LL long long #define MAXN 50005 #define rgt register int N, M, cnt[MAXN], mu[MAXN], p[MAXN], tot, v[MAXN]; LL s[MAXN]; LL ans(0); int main(){ scanf( "%d", &N ); for ( rgt int i = 1, x; i <= N; ++i ) scanf( "%d", &x ), ++cnt[x], M = max( M, x ); N = M, mu[1] = 1; for ( rgt int i = 2; i <= N; ++i ){//线性筛出mu if ( !v[i] ) p[++tot] = i, mu[i] = -1; for ( rgt int j = 1; j <= tot && i * p[j] <= N; ++j ){ v[i * p[j]] = 1; if ( i % p[j] == 0 ){ mu[i * p[j]] = 0; break; } else mu[i * p[j]] = -mu[i]; } } for ( rgt int i = 1; i <= N; ++i ) for ( rgt int j = i; j <= N; j += i ) s[j] += 1ll * mu[i] * i; for ( rgt int T = 1; T <= N; ++T ){ rgt LL cur(0); for ( rgt int i = 1, I = N / T; i <= I; ++i ) cur += 1ll * cnt[i * T] * i;//暴力求解 ans += T * cur * cur * s[T]; } printf( "%lld\n", ans ); return 0; }
持续更新中。。
Ans=\sum_{i=1}^n\sum_{j=1}^nlcm(i,j)\times c_i\times c_j
标签:string,第二届,ss,题解,49,大赛,int,正解,MAXN 来源: https://www.cnblogs.com/tscjj/p/14136622.html