2020.10.07【NOIP提高A组】模拟 JZOJ
6817. 【2020.10.07提高组模拟】DNA 序列
题目大意是给你一个长度 n<=5*10^6 的字符串,还有一个k<=10;字符串是由ACTG组成的,让你求这个字符串中所有连续k个字符组成的子串中,出现最多的一种的次数;
正解:由于k<=10;且只由4种元素组成所以,随便你怎么暴力都行,我这里用的是Trie
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int tree[1048600][4],i,j,n,m,k,l,len,a[5000005],root,tot,t[500005],ans; char s[5000001]; int max(int a,int b){return(a>b?a:b);} int main() { freopen("dna.in","r",stdin); freopen("dna.out","w",stdout); scanf("%s",s+1); scanf("%d",&n); len=strlen(s+1); for(i=1;i<=len;i++) if(s[i]=='A') a[i]=1;else if(s[i]=='C') a[i]=2;else if(s[i]=='G') a[i]=3;else a[i]=4; for(i=1;i<=len-n+1;i++) { root=0; for(j=i;j<=i+n-1;j++) { if(tree[root][a[j]]==0) tree[root][a[j]]=++tot; root=tree[root][a[j]]; } t[root]++;ans=max(ans,t[root]); } printf("%d",ans); return 0; }
6818. 【2020.10.07提高组模拟】数列递推
我们可以发现对于一个序列a它的值是正负交替的,直到同号为止,如为正那么它的值将越来越大否则将越来越小;
所以我们只要暴力出同号的位置,然后再往后找是否会有比前面的大或小,如果找到符合条件的比前面的大(小)的那么答案就是s[m]和(最小最大另一个的位置);否则答案就是前面大(小)的位置。
#include<cstdio> using namespace std; long long i,j,n,m,k,l,a[100001],ma,x,y,z,mi,mi1,ma1,num,cnt,tot,mi2,ma2,wz,wz1; int main() { freopen("seq.in","r",stdin); freopen("seq.out","w",stdout); scanf("%lld",&m); mi=mi1=1125899906842624; for(i=1;i<=m;i++) { scanf("%lld",&a[i]); if(ma<a[i])ma1=ma,ma=a[i]; else if(ma1<a[i]) ma1=a[i]; if(mi>a[i]) mi1=mi,mi=a[i]; else if(mi1>a[i]) mi1=a[i]; } scanf("%lld",&n); for(i=1;i<=n;i++) { scanf("%lld%lld%lld",&x,&y,&z); if(x==0&&y==0) printf("%lld %lld\n",a[1],a[1]);else if(x>0&&y>0) { if(mi==0&&mi1==1) { if(x<=y) printf("%lld %lld\n",ma,mi); else printf("%lld %lld\n",ma,mi1); } else printf("%lld %lld\n",ma,mi); } else if(x<0&&y<0) { if(mi==0&&mi1==1) { if(x>=y) printf("%lld %lld\n",mi,ma); else printf("%lld %lld\n",mi1,ma); } else printf("%lld %lld\n",mi,ma); } else { mi2=1125899906842624;ma2=-1125899906842624; if(a[1]==0) { if(x<mi2) mi2=x,wz=0; if(x>ma2) ma2=x,wz1=0; } if(a[1]==1||a[2]==1) { if(y<mi2) mi2=y,wz=1; if(y>ma2) ma2=y,wz1=1; } num=1;while(a[num]==0||a[num]==1&&num<=m) num++; tot=2; while(tot<=a[m]) { cnt=y*z+x; x=y;y=cnt; if(a[num]==tot) { if(cnt<mi2) mi2=cnt,wz=tot; if(cnt>ma2) ma2=cnt,wz1=tot; num++; } if(mi2==1125899906842624&&ma2==-1125899906842624&&((x>0&&y>0)||(x<0&&y<0))) { if(x>0&&y>0) printf("%lld %lld\n",a[m],a[1]); else printf("%lld %lld\n",a[1],a[m]); tot=a[m]+10; } else { if(mi2!=1125899906842624&&ma2!=-1125899906842624) { if(x>0&&y>0) { if(cnt>ma2)printf("%lld %lld\n",a[m],wz); else { while(cnt<=ma2&&tot<=a[m]) { tot++;cnt=y*z+x;x=y;y=cnt; if(a[num]==tot) { if(cnt<mi2) mi2=cnt,wz=tot; num++; } } if(cnt>ma2&&tot<=a[m]) printf("%lld %lld\n",a[m],wz); else printf("%lld %lld\n",wz1,wz); } tot=a[m]+10; } else if(x<0&&y<0) { if(cnt<mi2)printf("%lld %lld\n",wz1,a[m]); else { while(cnt>=mi2&&tot<=a[m]) { tot++;cnt=y*z+x;x=y;y=cnt; if(a[num]==tot) { if(cnt>ma2) ma2=cnt,wz1=tot; num++; } } if(cnt<mi2&&tot<=a[m]) printf("%lld %lld\n",wz1,a[m]); else printf("%lld %lld\n",wz1,wz); } tot=a[m]+10; } } } tot++; } if(tot==a[m]+1) printf("%lld %lld\n",wz1,wz); } } return 0; }
代码很丑仅供参考。
6819. 【2020.10.07提高组模拟】七曜圣贤 (sage)
这个我用的是水法,bitset优化,然后暴力就能过..........
完结。有什么问题评论区回复谢谢