蓝桥杯真题训练 五一 4/5
Posted iuk11
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蓝桥杯真题训练 五一 4/5相关的知识,希望对你有一定的参考价值。
1217 垒骰子
矩阵快速幂
op[i]表示的是与i的对面的数。
如果有面互斥,就在矩阵中标记为零,否则标记为4,代表顶和底确定的时候可以有四种情况。(矩阵乘法)
就是快速幂里面的乘法变成了矩阵乘法。
#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
typedef long long ll;
const int maxn=6;
ll n,m;
int a,b;
int vis[7][7];
int op[]={3,4,5,0,1,2};
void mul(int c[],int a[],int b[][maxn]){
int temp[maxn]={0};
for(int i=0;i<maxn;i++){
for(int j=0;j<maxn;j++){
temp[i]=(temp[i]+(ll)a[j]*b[j][i])%mod;
}
}
memcpy(c,temp,sizeof(temp));
}
void mull(int c[][maxn],int a[][maxn],int b[][maxn]){
int temp[maxn][maxn]={0};
for(int i=0;i<maxn;i++){
for(int j=0;j<maxn;j++){
for(int k=0;k<maxn;k++){
temp[i][j]=(temp[i][j]+(ll)a[i][k]*b[k][j])%mod;
}
}
}
memcpy(c,temp,sizeof(temp));
}
int main(){
cin>>n>>m;
for(int i=0;i<m;i++){
cin>>a>>b;
vis[a-1][b-1]=vis[b-1][a-1]=1;
}
int f[maxn]={4,4,4,4,4,4};
int a[maxn][maxn];
for(int i=0;i<maxn;i++){
for(int j=0;j<maxn;j++){
if(vis[j][op[i]]) a[j][i]=0;
else a[j][i]=4;
}
}
n--;
while(n){
if(n&1) mul(f,f,a);
mull(a,a,a);
n>>=1;
}
int res=0;
for(int i=0;i<maxn;i++){
res=(res+f[i])%mod;
}
cout<<res;
//system("pause");
return 0;
}
1221 四平方和
用了万能头,hash居然是关键字,这题算是巧妙暴力了,第一次循环的i,j相当于算出了c,d,第二次循环的i,j相当于在循环a,b,因为用 t=n-ixi-jxj 的式子是倒着推的,t一定一开始是大的,所以把当前的i,j当成小的,即a,b,然后has里面存的是i的值+1,再拿出来即可,另一个 d = s q r t ( n − a ∗ a − b ∗ b − c ∗ c ) d=sqrt(n-a*a-b*b-c*c) d=sqrt(n−a∗a−b∗b−c∗c)通过计算得到答案即可。
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e6+100;
int has[maxn];
int n;
int main(){
cin>>n;
for(int i=0;i*i<=n;i++){
for(int j=i;j*j+i*i<=n;j++){
if(!has[i*i+j*j]){
has[i*i+j*j]=i+1;
}
}
}
for(int i=0;i*i<=n;i++){
for(int j=0;j*j+i*i<=n;j++){
int t=n-i*i-j*j;
if(has[t]){
int c=has[t]-1;
int d=(sqrt(t-c*c));
printf("%d %d %d %d",i,j,c,d);
return 0;
}
}
}
}
1220 生命之树
这题有坑。。
后面说好的有向图。
定义的时候又是这么一手。相邻两点间有一条边相连的点集,就算。
那不就算无向图嘛。。
按无向图做,找个起点进去搜,定一个父节点保证不搜回去,死在里面。
然后一直搜到叶子节点,再不断回溯回来,回溯的过程中决定选或者不选,最后维护出一个最大的结果。
(这就是树形dp吗)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+100;
ll w[maxn];
vector<int> ve[maxn];
int n;
ll dp[maxn];
void dfs(int x,int fa){
dp[x]=w[x];
for(int i=0;i<ve[x].size();i++){
if(ve[x][i]==fa) continue;
dfs(ve[x][i],x);
dp[x]=max(dp[x],dp[x]+dp[ve[x][i]]);
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lld",&w[i]);
}
int u,v;
for(int i=1;i<n;i++){
scanf("%d%d",&u,&v);
ve[u].push_back(v);
ve[v].push_back(u);
}
dfs(1,-1);
ll ans=dp[1];
for(int i=2;i<=n;i++) ans=max(ans,dp[i]);
cout<<ans;
system("pause");
return 0;
}
总结:
五一该结束了,因为是广西省,蓝桥杯比第二场,所以还在准备当中。
到此为止也把古老的四五六届的真题写了一遍,感觉比区域赛铜牌题要亲切一些,也算是给每个算法打一个小基础,之前也了解过记忆化搜索,树状数组,还有DP,但是都是一知半解,这几天通过这些比较温柔的题目做了一个很好的吸收,对这些的算法理解更深刻了,对回溯理解也更深刻了。就连全排列也不仅用next_permutation了,又学了一手深搜的全排列,当然有局限性,还有STL里的hash,unordered_set等等。
明天是放假的最后一天,把这届第一场的真题补完(七八九十,十一之前都有写过)。然后该去补作业去了,该死的拖延症。
以上是关于蓝桥杯真题训练 五一 4/5的主要内容,如果未能解决你的问题,请参考以下文章
蓝桥杯选拔赛真题51Scratch赛车训练 少儿编程scratch图形化编程 蓝桥杯选拔赛真题讲解