C题 结婚改口
我们可以把qc视为一个整体,从前往后遍历字符串,对每一个a字符计算它前面的qc个数和后面的y的个数,两者相乘就是这个a所能组成的qcay的个数。把每个a字符所组成的qcay个数累加就是整个字符串的qcay的个数。同理可以计算qcjj的个数。
注意用long long不要用int,会爆的
#include <bits/stdc++.h> using namespace std; char s[(int)2e5+5]; long long c[(int)2e5+5];//从前往后 到i位置之前的合法的qc的个数 long long y[(int)2e5+5];//从后往前 i位置及之后的y的个数 long long j[(int)2e5+5];//从后往前 i位置及之后的j的个数 long long q[(int)2e5+5];//从前往后 到i位置之前的q的个数 int main() { int t; scanf("%d", &t); while (t--) { int n; scanf("%d%*c", &n);//不要漏掉%*c,不然会读出来一个换行符 for (int i=0; i<n; i++) { char ch; scanf("%c", &ch); s[i]=ch; } if (n<=3) //特判一下 { printf("qcjj\n"); continue; } y[n-1]=(s[n-1]=='y'?1:0); j[n-1]=(s[n-1]=='j'?1:0); y[n]=y[n-1]; //为了避免访问越界 j[n]=j[n-1]; for (int i=n-2; i>=0; i--) { y[i] = y[i+1]+(s[i]=='y'?1:0); j[i] = j[i+1]+(s[i]=='j'?1:0); } c[0]=0;//0位置可以忽略掉,因为它前面没有字符,所以到它为止一定没有qc q[0]=(s[0]=='q'?1:0); c[1]=(s[1]=='c'?q[0]:0);//当且仅当0位置为q,1位置为c时,到1为止存在一个qc q[1]=(s[1]=='q'?q[0]+1:q[0]); long long jj=0, ay=0; for (int i=2; i<n-1; i++) { q[i]=q[i-1]+(s[i]=='q'?1:0);//q的个数 c[i]=c[i-1]+(s[i]=='c'?q[i]:0);//qc的个数 if (s[i]=='a') ay+=c[i]*y[i];//a字符前面的qc的个数乘后面的y的个数,就是这个a所能组成的qcay的个数 else if (s[i]=='j') jj += c[i]*j[i+1];//qcjj的个数 } if (ay>=jj) printf("qcay\n");//测试发现,数量相等时好像也只能是两个中的一个 else printf("qcjj\n"); } }