题单详情 - 蓝桥云课 (lanqiao.cn)
填空题:
2360 互质
互质的定义是:两个数最大公约数为1,因此此题利用gcd模板即可AC:
#include<iostream>
using namespace std;
int ans;
int gcd(int a,int b){return b?gcd(b,a%b):a;
}
int main(){for(int i=1;i<=2020;i++) if(gcd(i,1018)==1) ans++;cout<<ans<<endl;return 0;
}
17121 混乘数字
下列代码肯定是超时的,但是此题为填空题,考试时先利用dev算出答案,最后直接输出结果即可:
#include<iostream>
#include<cstring>
using namespace std;
long long ans,flag[10],cnt[10];
bool check(long long x){memset(cnt,0,sizeof cnt);long long xx=x;while(xx>0){cnt[xx%10]++;xx/=10;}for(long long i=1;i*i<=x;i++){long long j=x/i;if(i*j==x){memset(flag,0,sizeof flag);long long ii=i,jj=j;int key=0;while(ii>0){flag[ii%10]++;ii/=10;}while(jj>0){flag[jj%10]++;jj/=10;}for(int k=0;k<=9;k++){if(flag[k]!=cnt[k]){key=1;break;}}if(key==0) return true;}}return false;
}
int main(){//for(int i=1;i<=1000000;i++) if(check(i)) ans++;//cout<<ans<<endl;cout<<590<<endl;return 0;
}
17133 逆元
费马小定理:
如果p是一个质数,而整数a不是p的倍数,则有a^(p-1) ≡ 1(mod p)
即 a^(p-1) = p*k+1 ,即 a*a^(p-2) =p*k+1乘法逆元的定义 :
如果 (a*x) mod p=1 ,即 a*x=p*k+1 ,则称x为a的模p的乘法逆元
乘法逆元的结论 :
a存在乘法逆元的充要条件是a与p互质,当p为质数时, a^p−2即为a的乘法逆元
fast_power AC:
#include<iostream>
using namespace std;
typedef long long ll;
const int p=2146516019;
int temp,ans;
int fast_power(int a,int b,int p){int res=1;while(b){if(b&1) res=(ll)res*a%p;b>>=1;a=(ll)a*a%p;}return res;
}
int main(){/*for(int i=1;i<=233333333;i++){temp=fast_power(i,p-2,p);ans^=temp;}cout<<ans<<endl;*/cout<<1307261675<<endl;return 0;
}
编程题:
18427 翻转
动态规划 AC:
#include<iostream>
#include<cstring>
using namespace std;
const int N=1e5+10;
char a[N][2];
int n,dp[N][2];
//dp[i][0]:前i个串拼在一起组成的min长度(第i个没有翻转)
//dp[i][1]:前i个串拼在一起组成的min长度(第i个有翻转)
int main(){cin>>n;for(int i=1;i<=n;i++) cin>>a[i];//初始化dp数组memset(dp,0x3f,sizeof dp);dp[1][0]=dp[1][1]=2;//动态规划for(int i=2;i<=n;i++){dp[i][0]=min(dp[i-1][0]+1+(a[i-1][1]!=a[i][0]),dp[i-1][1]+1+(a[i-1][0]!=a[i][0]));dp[i][1]=min(dp[i-1][0]+1+(a[i-1][1]!=a[i][1]),dp[i-1][1]+1+(a[i-1][0]!=a[i][1]));}cout<<min(dp[n][1],dp[n][0])<<endl;return 0;
}
17139 非对称二叉树
树形DP AC:
#include<iostream>
using namespace std;
const int N=40;
typedef long long ll;
ll n,m,ans,dp[N][N];
//dp[i][j]:有i个节点并且高度为j的非对称二叉树数量
int main(){cin>>n>>m;dp[0][0]=1;for(int i=1;i<=n;i++){for(int j=0;j<n;j++){int k=i-1-j; for(int hj=j;hj>=0;hj--){for(int hk=k;hk>=0;hk--){int maxx=max(hj,hk);int minn=min(hj,hk) ;if(maxx>=m*minn) dp[i][maxx+1]+=dp[j][hj]*dp[k][hk];}}}}for(int i=n;i>=0;i--) ans+=dp[n][i];cout<<ans<<endl;return 0;
}
6251 游戏
单调队列+双重循环 (未AC 40points):
#include<iostream>
#define int long long
using namespace std;
const int N=1e5+5;
int n,k,a[N],que[N],maxx[N],minn[N];
double ans;
signed main(){cin>>n>>k;for(int i=1;i<=n;i++) cin>>a[i];int head=0,tail=-1;for(int i=1;i<=n;i++){while(head<=tail&&que[tail]<a[i]) tail--;que[++tail]=a[i];if(i-k>=1&&que[head]==a[i-k]) head++;if(i>=k) maxx[i]=que[head];}head=0,tail=-1;for(int i=1;i<=n;i++){while(head<=tail&&que[tail]>a[i]) tail--;que[++tail]=a[i];if(i-k>=1&&que[head]==a[i-k]) head++;if(i>=k) minn[i]=que[head];}for(int i=k;i<=n;i++) for(int j=k;j<=n;j++) ans+=maxx[i]-minn[j];printf("%.2lf",ans/((n-k+1)*(n-k+1)));return 0;
}
优化:
for(int i=k;i<=n;i++) for(int j=k;j<=n;j++) ans+=maxx[i]-minn[j];
printf("%.2lf",ans/((n-k+1)*(n-k+1)));
--->--->--->
for(int i=k;i<=n;i++) ans+=maxx[i];
for(int i=k;i<=n;i++) res+=minn[i];
printf("%.2lf",(ans-res)/(n-k+1));
AC:
#include<iostream>
#define int long long
using namespace std;
const int N=1e5+5;
int n,k,a[N],que[N],maxx[N],minn[N];
double ans,res;
signed main(){cin>>n>>k;for(int i=1;i<=n;i++) cin>>a[i];int head=0,tail=-1;for(int i=1;i<=n;i++){while(head<=tail&&que[tail]<a[i]) tail--;que[++tail]=a[i];if(i-k>=1&&que[head]==a[i-k]) head++;if(i>=k) maxx[i]=que[head];}head=0,tail=-1;for(int i=1;i<=n;i++){while(head<=tail&&que[tail]>a[i]) tail--;que[++tail]=a[i];if(i-k>=1&&que[head]==a[i-k]) head++;if(i>=k) minn[i]=que[head];}for(int i=k;i<=n;i++) ans+=maxx[i];for(int i=k;i<=n;i++) res+=minn[i];printf("%.2lf",(ans-res)/(n-k+1));return 0;
}
17152 最大区间
单调栈 AC:
#include<iostream>
#include<cstring>
#define int long long
using namespace std;
const int N=3e5+5;
int n,a[N],stackk[N],top,l[N],r[N],ans;
signed main(){cin>>n;for(int i=1;i<=n;i++) cin>>a[i];a[0]=a[n+1]=-1;top=0;stackk[++top]=0;for(int i=1;i<=n;i++){while(a[stackk[top]]>=a[i])top--;l[i]=stackk[top];stackk[++top]=i;}top=0;stackk[++top]=n+1;for(int i=n;i;i--){while(a[stackk[top]]>=a[i]) top--;r[i]=stackk[top];stackk[++top]=i;}for(int i=1;i<=n;i++) ans=max(ans,(r[i]-l[i]-1)*a[i]);cout<<ans<<endl;return 0;
}
17147 最大阶梯
动态规划 AC:
#include<iostream>
#include<cstring>
#define int long long
using namespace std;
const int N=1e3+5;
int n,h[N][N],dp[N][N],ans;
void init(){for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) dp[i][j]=1;
}
signed main(){ios::sync_with_stdio(false);cin>>n;memset(h,-1,sizeof h);for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) cin>>h[i][j];//比较左边和上面init();for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){if(h[i][j]==h[i][j-1]&&h[i][j]==h[i-1][j]){dp[i][j]=min(dp[i][j-1],dp[i-1][j])+1;ans=max(ans,dp[i][j]);}}}//比较左边和下面init();for(int i=n;i>=1;i--){for(int j=1;j<=n;j++){if(h[i][j]==h[i][j-1]&&h[i][j]==h[i+1][j]){dp[i][j]=min(dp[i][j-1],dp[i+1][j])+1;ans=max(ans,dp[i][j]);}}}//比较右边和上面init();for(int i=1;i<=n;i++){for(int j=n;j>=1;j--){if(h[i][j]==h[i][j+1]&&h[i][j]==h[i-1][j]){dp[i][j]=min(dp[i][j+1],dp[i-1][j])+1;ans=max(ans,dp[i][j]);}}}//比较右边和下面init();for(int i=n;i>=1;i--){for(int j=n;j>=1;j--){if(h[i][j]==h[i][j+1]&&h[i][j]==h[i+1][j]){dp[i][j]=min(dp[i][j+1],dp[i+1][j])+1;ans=max(ans,dp[i][j]);}}}cout<<ans<<endl;return 0;
}
17117 火车运输
动态规划背包问题 AC:
#include<iostream>
#define int long long
using namespace std;
const int N=1005;
int n,A,B,w[205],dp[N][N];
signed main(){ios::sync_with_stdio(false);cin>>n>>A>>B;for(int i=1;i<=n;i++) cin>>w[i];for(int i=1;i<=n;i++){for(int j=A;j>=0;j--){for(int k=B;k>=0;k--){if(j>=w[i]) dp[j][k]=max(dp[j][k],dp[j-w[i]][k]+w[i]);if(k>=w[i]) dp[j][k]=max(dp[j][k],dp[j][k-w[i]]+w[i]);}}}cout<<dp[A][B]<<endl;return 0;
}