AtCoder Regular Contest 071
传送门
C - 怪文書 / Dubious Document
题意:定义一种无序的子序列:在原串中随意地取字符并随意打乱顺序。求多个字符串的最长公共无序子序列。
#include<cstdio> #include<algorithm> using namespace std; int n,m,s[26],q[26]; char c[100]; int main(){ scanf("%d",&n); for (int i=0;i<26;i++) s[i]=51; while (n--){ scanf("%s",c); for (int i=0;i<26;i++) q[i]=0; for (int i=0;c[i];i++) q[c[i]-'a']++; for (int i=0;i<26;i++) s[i]=min(s[i],q[i]); } for (int i=0;i<26;i++) while (s[i]--) putchar('a'+i); }
D - 井井井 / ###
题意:求平行坐标轴的多条直线围成的所有矩形的面积和。
#include<cstdio> #include<algorithm> #define MN 200001 using namespace std; const int MOD=1e9+7; int n,m,a[MN],b[MN],A=0,B=0; int main(){ scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%d",&a[i]);sort(a+1,a+1+n); for (int i=1;i<=m;i++) scanf("%d",&b[i]);sort(b+1,b+1+m); for (int i=1;i<n;i++) A=(1LL*(a[i+1]-a[i])*i%MOD*(n-i)+A)%MOD; for (int i=1;i<m;i++) B=(1LL*(b[i+1]-b[i])*i%MOD*(m-i)+B)%MOD; printf("%lld\n",1ll*A*B%MOD); }
E - TrBBnsformBBtion
定义几种变换:A->BB,B->AA,AAA->空,BBB->空。先给两个字符串,每次询问它们的两个子串是否能相互转换。
题解:将A当成1,B当成2,一个字符串的值为所有字符的和,那么只需要两个字符串的值模3意义下同于即可相互转换。
#include<cstdio> #include<algorithm> #define MN 200001 using namespace std; const int MOD=1e9+7; int qa[MN],qb[MN],n,x,y,X,Y; char a[MN],b[MN]; int main(){ scanf("%s%s",a+1,b+1); for (int i=1;a[i];i++) qa[i]=qa[i-1]+a[i]-'A'+1; for (int i=1;b[i];i++) qb[i]=qb[i-1]+b[i]-'A'+1; scanf("%d",&n); while(n--){ scanf("%d%d%d%d",&x,&y,&X,&Y); puts((qa[y]-qa[x-1])%3==(qb[Y]-qb[X-1])%3?"YES":"NO"); } }
F - Infinite Sequence
求满足下列条件的无穷序列数量:
数字在1到n之间。
an与后面所有项相等。
ai后面的ai个项相等。
题解:dp即可。
#include<cstdio> #include<algorithm> #define MN 1000001 using namespace std; const int MOD=1e9+7; int n,f[MN],m; inline void M(int &x){while(x>=MOD)x-=MOD;} int main(){ int i,j; scanf("%d",&n);f[n]=n;m=n-1; for (i=n-1;i;i--) f[i]=1LL*(n-1)*(n-1)%MOD,M(f[i]+=f[i+1]),M(f[i]+=m),M(m+=(i+2>n?1:f[i+2])-1); printf("%d\n",f[1]); }
这几乎是我打过码量最少的比赛。