这个东西已经咕咕咕了快一年的时间,想想昨天校内训练差点被学弟们爆锤,真是怠惰啊..._(:з」∠)_
从开始刷教育轮的蓝名水平,到“Educational Round补完计划”开启时的紫名中游水平,再到现在个人水平也游到了黄名中下游,应该是不需要用狂刷div2的水题来提升自我了,不过既然当初挖了这个坑,还是要补一下的...一年多时间教育轮的轮数也从当时的50到了现在的80+,感觉很难在退役前补完了_(:з」∠)_先试试能不能把50轮之前的都搞定吧...
660A - Co-prime Array 20171129
看了一眼我当年写的代码...这什么憨批玩意嘛_(:з」∠)_
#include<stdlib.h> #include<stdio.h> #include<math.h> #define N 1001 #include<vector> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int n,k,a[N],p[20]; vector<int>ans; int gcd(int x,int y){return y?gcd(y,x%y):x;} int find(int x,int y) { for(int i=1;i<20;i++) if(gcd(x,p[i])==1 && gcd(y,p[i])==1) return p[i]; } int main() { p[1]=2,p[2]=3,p[3]=5,p[4]=7,p[5]=11; p[6]=13,p[7]=17,p[8]=19,p[9]=23,p[10]=29; p[11]=31,p[12]=37,p[13]=41,p[14]=43; p[15]=47,p[16]=53,p[17]=59,p[18]=61,p[19]=67; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); ans.push_back(0); ans.push_back(a[1]); for(int i=2;i<=n;i++) { if(gcd(a[i],a[i-1])!=1) k++,ans.push_back(find(a[i],a[i-1])); ans.push_back(a[i]); } printf("%d ",k); for(int i=1;i<=n+k;i++) printf("%d%c",ans[i],i==(n+k)?' ':' '); return 0; }
实际上每次输入的时候只需要判断下和之前是否互质就好,如果互质的话直接push_back,否则在这之前直接插入一个1即可
#include<bits/stdc++.h> using namespace std; int n,x,a[1001],k; vector<int>d; int main() { scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%d",&a[i]); if(d.empty() || __gcd(a[i],d.back())==1)d.push_back(a[i]); else d.push_back(1),k++,d.push_back(a[i]); } printf("%d ",k); for(auto i:d)printf("%d ",i); }
660B - Seating On Bus 20171129
看了眼代码好像是道奇怪的递推...?这个配图好像某次开火车的时候还见过...
#include<stdlib.h> #include<stdio.h> #include<math.h> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int n,m,a[101][4]; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { a[i][1]=2*i-1; a[i][0]=2*n+a[i][1]; a[i][3]=2*i; a[i][2]=2*n+a[i][3]; } for(int i=1;i<=n;i++) for(int j=0;j<4;j++) if(a[i][j]<=m) printf("%d ",a[i][j]); printf(" "); return 0; }
660C - Hard Process 20171129
对于每个左端点,对应的最大合法区间的右端点一定是单调升的,故可以使用 滑窗/尺取法/双指针 来求解(这东西名字好多,CF上标的是two pointers)
#include<stdlib.h> #include<stdio.h> #include<math.h> #define N 300001 #include<cstring> #include<iostream> #include<algorithm> using namespace std; int n,k,a[N],s,l,r=1,ans,L,R; int main() { scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) scanf("%d",&a[i]),a[i]^=1; while(++l<=n) { while(r<=n && s+a[r]<=k)s+=a[r++]; if(r-l>ans)ans=r-l,R=r,L=l; s-=a[l]; } printf("%d ",ans); for(int i=1;i<=n;i++) printf("%d%c",(L<=i && i<R)?1:a[i]^1,i==n?' ':' '); return 0; }
660D - Number of Parallelograms 20171129
把每两个点间对应的向量存下来,求每种向量的出现次数即可,当年用的是憨批sort外加手动赋值的做法还调了半天,实际上一个map<pair<int,int>>就能完美解决问题(STL大法好)
#include<stdlib.h> #include<stdio.h> #include<math.h> #define N 2001 #include<vector> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define LL long long vector<LL>m; LL n,ans,x[N],y[N]; int main() { scanf("%I64d",&n); for(LL i=1;i<=n;i++) scanf("%I64d%I64d",&x[i],&y[i]); m.push_back(0ll); for(LL i=1;i<=n;i++) for(LL j=i+1;j<=n;j++) m.push_back((x[i]+x[j])*2000000001ll+(y[i]+y[j])); sort(m.begin(),m.end()); LL _=0; for(LL i=1;i<m.size();i++) if(m[i]!=m[i-1]) ans+=_*(_-1)/2,_=1; else _++; printf("%I64d ",ans); return 0; }
660E - Different Subsets For All Tuples 20171129
我当年推的是什么傻逼式子啊_(:з」∠)_有空再重新做下...
#include<stdlib.h> #include<stdio.h> #include<math.h> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define LL long long #define MOD 1000000007 LL qow(LL x,LL y){return y?(y&1?x*qow(x,y-1)%MOD:qow(x*x%MOD,y/2)):1;} LL n,m,s,ans; int main() { scanf("%I64d%I64d",&n,&m); ans=qow(m,n);s=qow(m-1,n-1)*m%MOD; for(LL k=1;k<n;k++) ans+=s,s*=m*(n-k+1)%MOD,s%=MOD,s*=qow((m-1)*k%MOD,MOD-2),s%=MOD; printf("%I64d ",m==1?n+1:(ans+s)%MOD); return 0; }
660F - Bear and Bowling 4 20171129
好像写的是个比较丢人的三分外加调参乱搞...当时我应该是面向数据编程过的...
#include<stdlib.h> #include<stdio.h> #include<math.h> #define N 200001 #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define LL long long LL ans,n,l,r,a[N],f[N]; LL get(LL l) { LL res=0; for(LL i=1;i<=n-l;i++) res=max(res,f[i+l]-f[i-1]-(i-1)*(a[i+l]-a[i-1])); return res; } int main() { scanf("%I64d",&n); for(LL i=1;i<=n;i++) scanf("%I64d",&a[i]),f[i]=f[i-1]+i*a[i],a[i]+=a[i-1]; r=n; while(r-l>2) { LL m1=(2*l+r)/3,m2=(l+2*r)/3; if(get(m1)<get(m2))l=m1;else r=m2; } for(LL i=max(0ll,l-1000);i<=min(n,r+1000);i++) ans=max(ans,get(i)); printf("%I64d ",ans); return 0; }