总体来说,这次校赛打的中规中矩,算是正常发挥吧。过了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就不写了,本身过的人也不多(比较难)~
总结一下就是不会的东西还很多,思路受阻。明年再努力吧~