本文主要是介绍2021.8.9 提高B组模拟赛,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
2021.8.9 2021.8.9 2021.8.9 模拟赛
目录:
T1.最长公共回文子序列
T2.QYQ在艾泽拉斯
T3.平均数
T4.着色
T 1 : T1: T1:最长公共回文子序列
分析:
在 B B B串里枚举回文子串 然后看这个子串在 A A A串有没有即可
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1e5+5;
char a[N],b[25],s[25];
int n,m,ans,vis[N],tot;
void dfs(int x)
{if(x>m){tot=0;for(int i=1;i<=m;i++)if(vis[i]) s[++tot]=b[i];for(int i=1;i<=(tot>>1);i++)if(s[i]!=s[tot-i+1]) return;int j=1;for(int i=1;i<=n;i++){if(a[i]==s[j]) j++;if(j>tot) break;}if(j<=tot) return;ans=max(ans,tot);return;}vis[x]=1; dfs(x+1);vis[x]=0; dfs(x+1);
}
int main(){freopen("lcps.in","r",stdin);freopen("lcps.out","w",stdout);scanf("%s%s",a+1,b+1);n=strlen(a+1);m=strlen(b+1);dfs(1);printf("%d",ans);return 0;
}
T 2 : Q Y Q T2:QYQ T2:QYQ在艾泽拉斯
分析:
t a r j a n tarjan tarjan把所有岛屿都先处理出
然后在拓扑序里 把每个连通块最大路径值求出 这个用并查集和拓扑序 d p dp dp做
答案就是前 k k k个之和
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<stack>
using namespace std;
typedef long long ll;
const int N=1e6+5;
int n,m,k,tot,head[N],x[N],y[N];
int low[N],dfn[N],con[N],Index,size;
int fa[N],in[N],num,head2[N],tot2;
ll f[N],Ans,ans[N],w[N],val[N],sum[N];
queue<int> q;
stack<int> st;
struct node{int to,next;
}a[N],a2[N];
void add(int x,int y)
{a[++tot]=(node){y,head[x]};head[x]=tot;
}
void add2(int x,int y)
{a2[++tot2]=(node){y,head2[x]};head2[x]=tot2;
}
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
void tarjan(int x)
{st.push(x);dfn[x]=low[x]=++Index;for(int i=head[x];i;i=a[i].next){int qwq=a[i].to;if(!dfn[qwq]){tarjan(qwq);low[x]=min(low[x],low[qwq]);}else if(!con[qwq])low[x]=min(low[x],dfn[qwq]);}if(dfn[x]==low[x]){con[x]=++size;sum[size]=w[x];while(st.top()^x){con[st.top()]=size;sum[size]+=w[st.top()];st.pop();}st.pop();}
}
void TpSort()
{while(!q.empty()){int x=q.front();q.pop();for(int i=head2[x];i;i=a2[i].next){int qwq=a2[i].to;if(val[x]+sum[qwq]>val[qwq]){val[qwq]=val[x]+sum[qwq];int now=find(qwq);f[now]=max(f[now],val[qwq]);}in[qwq]--;if(in[qwq]==0) q.push(qwq);}}
}
void merge(int x,int y){(x<y)?fa[y]=x:fa[x]=y;}
int main(){freopen("azeroth.in","r",stdin);freopen("azeroth.out","w",stdout);scanf("%d%d",&n,&m);for(int i=1;i<=m;i++){scanf("%d%d",&x[i],&y[i]);add(x[i],y[i]);}for(int i=1;i<=n;i++)scanf("%lld",&w[i]);scanf("%d",&k);for(int i=1;i<=n;i++)if(!dfn[i]) tarjan(i);for(int i=1;i<=size;i++)fa[i]=i;for(int i=1;i<=m;i++){int a=x[i],b=y[i];if(con[a]^con[b]){int fx=find(con[a]),fy=find(con[b]);merge(fx,fy);in[con[b]]++;add2(con[a],con[b]);}}for(int i=1;i<=size;i++)if(in[i]==0){q.push(i); val[i]=sum[i];int now=find(i);f[now]=max(f[now],val[i]);}TpSort();for(int i=1;i<=size;i++)if(f[i]) ans[++num]=f[i];sort(ans+1,ans+num+1);for(int i=num;i>=max(1,num-k);i--)Ans+=ans[i];printf("%lld",Ans);return 0;
}
T 3 : T3: T3:平均数
L u o g u Luogu Luogu l i n k link link & \& & 双倍经验
分析:
二分
如果一个序列的平均值 > x >x >x 那每个数 − x > 0 -x>0 −x>0 所以二分这个 x x x
枚举前缀和 若当前前缀和 减 最小前缀和 > 0 >0 >0 x x x即合法
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=3e5+5;
int n,k,a[N];
double ans,eps=1e-7,sum[N],l=0,r;
bool check(double x)
{for(int i=1;i<=n;i++)sum[i]=sum[i-1]+(double)(a[i]-x);double tmp=0;for(int i=1;i<=n;i++)if(i-k>=0){tmp=min(tmp,sum[i-k]);if(sum[i]-tmp>=0) return 1;}return 0;
}
int main(){freopen("average.in","r",stdin);freopen("average.out","w",stdout);scanf("%d%d",&n,&k);for(int i=1;i<=n;i++){scanf("%d",&a[i]);r+=a[i];}while(r-l>eps){double mid=(l+r)/2.0;if(check(mid)) l=mid,ans=l;else r=mid;}printf("%.6lf",ans);return 0;
}
T 4 : T4: T4:着色
L u o g u Luogu Luogu l i n k link link
分析:
k = 2 k=2 k=2时 答案都为 2 2 2
如果图能用两色或三色涂 a n s = ans= ans=两色答案 × C k 2 + ( \times C_k^2+( ×Ck2+(三色答案 − 6 ) × C k 3 -6)\times C_k^3 −6)×Ck3
如果只能用三色涂 a n s = ( ans=( ans=(三色答案 − 6 ) × C k 3 -6)\times C_k^3 −6)×Ck3
− 6 -6 −6是从三色中减去两色的方案数
三色时的答案可以手算 可以从样例里找 也可以 d f s dfs dfs
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
long long n,k;
int main(){freopen("color.in","r",stdin);freopen("color.out","w",stdout);scanf("%lld%lld",&n,&k);long long C_2=k*(k-1)/2,C_3=k*(k-1)*(k-2)/6;if(n==1) printf("%lld",2*C_2+1572858*C_3); else if(n==2) printf("%lld",96*C_3);else if(n==3) printf("%lld",2*C_2+18*C_3);else if(n==4) printf("%lld",2*C_2+24570*C_3);else if(n==5) printf("%lld",12*C_3);else if(n==6) printf("%lld",6*C_3);else if(n==7) printf("%lld",96*C_3);else if(n==8) printf("%lld",2*C_2+((1<<30)+2ll-6ll)*C_3);return 0;
}
这篇关于2021.8.9 提高B组模拟赛的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!