总体来说,这次校赛打的中规中矩,算是正常发挥吧。过了4题,依靠罚时取得了还不错的成绩。
下面发出一些题的题解(有的参考了其他人的思路)
--------------------------------------------------------------------------------------------------------------------------------
A题
大水题,就不啰嗦了,直接上代码
#include<cstdio> #include<cstring> using namespace std; char word[25]; int main() { int t; scanf("%d",&t); for(int i=0;i<t;i++) { scanf("%s",word); if(strcmp(word,"zero")==0) printf("ling\n"); else if(strcmp(word,"one")==0) printf("yi\n"); else if(strcmp(word,"two")==0) printf("er\n"); else if(strcmp(word,"three")==0) printf("san\n"); else if(strcmp(word,"four")==0) printf("si\n"); else if(strcmp(word,"five")==0) printf("wu\n"); else if(strcmp(word,"six")==0) printf("liu\n"); else if(strcmp(word,"seven")==0) printf("qi\n"); else if(strcmp(word,"eight")==0) printf("ba\n"); else if(strcmp(word,"nine")==0) printf("jiu\n"); else if(strcmp(word,"ten")==0) printf("shi\n"); } return 0; }
B题
直接暴力找就可以了,复杂度O(mn)
#include<cstdio> #include<vector> #include<algorithm> #include<cmath> #include<cstdlib> #include<cstring> #include<iostream> #include<queue> using namespace std; char zimu[110]; char dian[1010][20]; int flag[30]; int main() { int n; while(scanf("%s",zimu)!=EOF) { memset(flag,0,sizeof(flag)); int len=strlen(zimu); for(int i=0;i<len;i++) flag[zimu[i]-'a']=1; scanf("%d",&n); for(int i=0;i<n;i++) scanf("%s",dian[i]); int maxn=0; for(int i=0;i<n;i++) { int f=1; int len1=strlen(dian[i]); for(int j=0;j<len1;j++) { if(flag[dian[i][j]-'a']!=1) f=0; } if(f==1) maxn=max(len1,maxn); } printf("%d\n",maxn); } return 0; }
C题
不能暴力做,会超时(我最开始头铁T了2发)。找规律,如1,2,3,4,5会发现1出现4次,2出现3次,3出现2次,4出现1次。所以先排个序,每个数出现的次数就固定了。
#include<cstdio> #include<vector> #include<algorithm> #include<cmath> #include<cstdlib> #include<cstring> #include<iostream> #include<queue> int a[2600]; int res[3200000]; int num[2600]; using namespace std; bool cmp(int a1,int a2) { return a1>a2; } int main() { int n,k,t; scanf("%d",&t); for(int i=0;i<t;i++) { int u=0; scanf("%d%d",&n,&k); for(int j=0;j<n;j++) { scanf("%d",&a[j]); } sort(a,a+n); for(int j=0;j<n;j++) { num[j]=n-j-1; } for(int j=0;j<n;j++) { while(num[j]) { num[j]--; res[u++]=a[j]; } } printf("%d\n",res[n*(n-1)/2-k]); //sort(res,res+u,cmp); //printf("%d\n",res[k-1]); } return 0; }
D题
我还是找规律,其实规律也很简单,就是sum/n(窝太弱了,规律不会证。。。)
#include<cstdio> #include<vector> #include<algorithm> #include<cmath> #include<cstdlib> #include<cstring> #include<iostream> #include<queue> int a[1010]; using namespace std; int main() { int n,t; scanf("%d",&t); for(int i=0;i<t;i++) { int sum; sum=0; scanf("%d",&n); for(int j=0;j<n;j++) { scanf("%d",&a[j]); sum+=a[j]; } sort(a,a+n); printf("%d\n",sum/n); } return 0; }
E题
一道dp题,看了赛后给的思路才会做(窝太弱了。。。)。dp[i][j],i表示以i结尾,j表示模为j。线性复杂度,详见代码。(不要忘了开long long)
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int dp[1000010][3]; char s[1000010]; int main() { while(scanf("%s",s)!=EOF) { long long int sum=0; if(s[0]=='0') { dp[0][0]=1; dp[0][1]=0; dp[0][2]=0; } else if(s[0]=='1') { dp[0][0]=0; dp[0][1]=1; dp[0][2]=0; } sum+=dp[0][0]; int len=strlen(s); for(int i=1;i<len;i++) { if(s[i]=='0') { dp[i][0]=dp[i-1][0]+1; dp[i][1]=dp[i-1][2]; dp[i][2]=dp[i-1][1]; } else if(s[i]=='1') { dp[i][0]=dp[i-1][1]; dp[i][1]=dp[i-1][0]+1; dp[i][2]=dp[i-1][2]; } sum+=dp[i][0]; } printf("%lld\n",sum); } return 0; }
F题
思路参考了
https://blog.csdn.net/qq_40772738/article/details/80034829,用set维护啊,不知道set自带排序,导致比赛时一直TLE。
#include<cstdio> #include<set> #include<map> #include<cstring> using namespace std; typedef pair<int,int> P; int a[50010]; int b[50010]; int ok[50010]; int main() { int n,m,q; set<P> s; while(scanf("%d%d%d",&n,&m,&q)!=EOF) { int ans=0; memset(b,0,sizeof(b)); memset(ok,0,sizeof(ok)); s.clear(); for(int i=0;i<q;i++) { scanf("%d",&a[i]); b[a[i]]++; } for(int i=0;i<q;i++) { if(!ok[a[i]]) { if(s.size()<n) { s.insert(P(b[a[i]],a[i])); ok[a[i]]=1; ans++; } else { ans++; set<P>::iterator it; it=s.begin(); int tem=(*it).second; s.erase(it); ok[tem]=0; s.insert(P(b[a[i]],a[i])); ok[a[i]]=1; } } else { s.erase(P(b[a[i]],a[i])); b[a[i]]--; s.insert(P(b[a[i]],a[i])); } } printf("%d\n",ans); } return 0; }
G题
很坑,网络赛题的升级版。当时用搜索做的,这次过不了。标程给的dp,我觉得用素数筛更好一些,再加上找规律。就等于n的所有(素数-1)的和。这道题当时没做出来有些可惜~~
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int MAXN = 1000000; int prime[MAXN + 1]; void getPrime() { memset(prime, 0, sizeof(prime)); for (int i = 2; i <= MAXN; i++) { if (!prime[i]) { prime[++prime[0]] = i; } for (int j = 1; j <= prime[0] && prime[j] <= MAXN / i; j++) { prime[prime[j] * i] = 1; if (i % prime[j] == 0) { break; } } } return ; } long long factor[100][2]; int fatCnt; int getFactors(long long x) { fatCnt = 0; long long tmp = x; for (int i = 1; prime[i] <= tmp / prime[i]; i++) { factor[fatCnt][1] = 0; if (tmp % prime[i] == 0) { factor[fatCnt][0] = prime[i]; while (tmp % prime[i] == 0) { factor[fatCnt][1]++; tmp /= prime[i]; } fatCnt++; } } if (tmp != 1) { factor[fatCnt][0] = tmp; factor[fatCnt++][1] = 1; } return fatCnt; } int main() { int t,n; scanf("%d",&t); getPrime(); while(t--) { int sum=0; scanf("%d",&n); int len=getFactors(n); for(int i=0;i<len;i++) { sum+=(factor[i][0]-1)*factor[i][1]; } printf("%d\n",sum); } return 0; }
H,I,J就不写了,本身过的人也不多(比较难)~
总结一下就是不会的东西还很多,思路受阻。明年再努力吧~