入门赛2

前言

这是一个蒟蒻的比赛心得与代码,请各位dalao不要嫌弃。

本赛涉及题目:
A: [Odds and Ends]

B: [Tell Your World]

C: [From Y to Y]

D: [Harmony Analysis]

E: [Bear and Prime Numbers]


T1 Odds and Ends

题面

原题地址: [A]

题意

问能否将数组分割成奇数个长度为奇数,头尾都为奇数的集合。

思路

(2*a+1)*(2*k+1)=2*p+1—->>n必为奇数;
此时母串就是一个集合,只要满足头尾都为奇数就行了。
【易证头或尾为偶数时必不能完成题面】

代码

#include<bits/stdc++.h>
using namespace std;
int i,n,x;
int main()
{
    scanf("%d",&n);
    if(!n&1)//n的奇偶性;
    {
        printf("No");
        return 0;
    }
    for(i=1;i<=n;i++)
    {
        scanf("%d",&x);
        if(i==1||i==n)//头尾的奇偶性;
        {
            if(!x&1)
            {
                printf("No");
                return 0;
            }
        }
    }
    printf("Yes");
    return 0;
} 

小结

水题*1


T2 Tell Your World

题面

原题地址: [B]

题意

能否找到两条平行线使所有点都在这两条线上。

思路

找平行线的斜率,枚举点。
斜率k有n*n种可能,枚举点再*n,绝对TLE。
此时我们发现,如果斜率k不是(1,2),(2,3),(1,3)的斜率,这个k必定不能满足题面(自己证)。
于是我们只用枚举三个k。时间复杂度O(n)过。

代码

#include<bits/stdc++.h>  
using namespace std;  
int s[3000],n,p,i;  
bool if_line(double k)//寻找这个k是否能行;
{  
    p=-1;  
    for(i=2;i<=n;i++)  
    {  
        if(s[i]-s[1]!=k*(i-1))//第一条线不满足;
        {
            if(p==-1) p=i;  
            else
            {
                if(s[i]-s[p]!=k*(i-p))  return false; //第二条平行线的构造;
            } 
        } 
    }  
    return p!=-1;  
}  
int main()  
{  
    scanf("%d",&n);
    for(i=1;i<=n;i++) scanf("%d",&s[i]);  
    if_line(s[2]-s[1])||if_line((s[3]-s[1])*0.5)||if_line(s[3]-s[2])?printf("Yes"):printf("No");    
}

小结

要枚的三个k手算得我一脸懵逼(可惜这是关键)


T3 From Y to Y

题面

原题地址: [C]

题意

有一个串,将这个串分成长度为1的n个子串,再将这些子串合并,合并成母串的最小代价k。
代价:两个合并子串s,t中重复字母的总个数。

给出k,求原串(有多种可能,只输出一种)。

思路

同种字母合并才会产生代价,于是我们可以先将同种字母合并,再合并由同种字母组成的字符串。
此时再通过计算发现无论什么合并方式,代价都是l*(l-1)/2。
枚’a’…’z’的l,使总代价=k。

代码

#include<bits/stdc++.h>
using namespace std;
int cur,k,n,i;
int main()
{
    scanf("%d",&n);n*=2;
    if(n==0)//特判(本代码对0没有任何抵抗力);
    {
        printf("a");
        return 0;
    }
    while(n)
    {
        k=1;
        while(k*(k+1)<=n) k++;//第cur+1个字母的个数;
        for(n-=k*(k-1),i=1;i<=k;i++) printf("%c",cur+'a');
        cur++;//下一个字母;
    }
    return 0;
}

小结

代价恒为最小值是重点!!!


T4 Harmony Analysis

题面

原题地址: [D]

题意

每两行保证有n组相同点(竖着的两字符一样即为相同),每行仅由’+’与’*’组成;

思路

第k个图形由第k-1个图形向下,向右复制一份,向右下复制一遍反的(’+”*’互逆)。
手动画图推。。。(如果有dalao知道数学证明,请告知一下!!)

代码

#include<bits/stdc++.h>
#define M 1<<9
using namespace std;
char t[M][M];
int l=1,n,e,i,j;
int main()
{
    scanf("%d",&n);t[0][0]='+';
    for(e=1;e<=n;e++)//递推次数;
    {
        for(i=0;i<l;i++)
        {
            for(j=0;j<l;j++)
            {
                t[i+l][j]=t[i][j+l]=t[i][j];//等位复制;
                t[i+l][j+l]=t[i][j]=='+'?'*':'+';//反复制;
            }
        }
        l*=2;
    }
    for(i=0;i<1<<n;i++)
    {
        for(j=0;j<1<<n;j++)
        {
            printf("%c",t[i][j]);
        }
        printf("\n");
    }
    return 0;
}

小结

手蒙推递推式花了不少时间!!!


T5 Bear and Prime Numbers

题面

原题地址: [E]

Ps:

其他题基本就是一遍A,但这道题却交了不少次啊!!!

题意

有n个数a[i]..a[n],有m个询问,询问[li,ri]中f(p)的总和(p<-[li,ri])。
定义f(p)(p为素数)=(n个数中有多少个数整除p)。

思路

直接以询问进行暴力,绝对TLE,所以必定需要优化:我们发现询问很多,可以把各种f(p)先算出来(埃氏筛),再在区间内直接算,但这还不够,还是TLE,还可以用前缀和进行优化,然后就AC了。。。

WA的过程

1.MLE

li,ri<=2*10^9,但数组开不到10^9(本地就炸),10^8(MLE);然而用到的最大质数是min(ri,a[i]),而a[i]max=10^7;所以数组开到10^7就行了。

2.RE

a[i]<=10^7,但li,ri<=2*10^9,这样就会在算区间时莫名其妙访问错误地址,然后RE。

3.TLE

素数筛法

常规质数筛法为O(n^2),马上就TLE了,然后就可以改成埃氏筛O(n log^2 n),或线性筛(我也不知道叫什么)。
此时选用埃氏筛是因为这种筛法会遍历一遍素数p的倍数,与题意相符。

for(i=2;i<=MaxN;i++)
{
  if(!if_prime[i])
  {
      prime[cur]=i;
      cur++;
      for(j=i+i;j<=MaxN;j++) if_prime[j]=true;//遍历i(素数)的倍数;
  }
}

于是可以改成,下文中的样子。

f(p)的合并

原本想从li到ri for一遍,不过TLE了,再看数据范围m<=50000,于是就可以用前缀和维护,预处理费时,但后来都是O(1)求answer。

代码

#include<bits/stdc++.h>
#define maxn 10000005
using namespace std;
int t[10000007],n,i,j,x,y,ans,m,sum[10000007];
bool p[10000007];
int main()
{
    scanf("%d",&n);
    while(n--)
    {
        scanf("%d",&x);
        t[x]++;
    }
    for(i=2;i<=maxn;i++)//埃氏筛;
    {
        if(!p[i])
        {
            sum[i]=t[i];
            for(j=i+i;j<=maxn;j+=i)
            {
                p[j]=true;
                if(t[j]) sum[i]+=t[j];//小优化:直接推f(p);
            }
        }
    }
    for(i=1;i<=maxn;i++)//维护前缀和;
    {
        sum[i]+=sum[i-1];
    }
    scanf("%d",&m);
    while(m--)
    {
        ans=0;
        scanf("%d%d",&x,&y);
        if(x!=maxn) x=min(x,maxn-1);y=min(y,maxn);//防止数组下标越界;
        ans=sum[y]-sum[x-1];
        printf("%d\n",ans);
    }
    return 0;
}

小结

题面很重要,数据范围很重要,算法更重要!!!


总结

这次比赛还差最后一道题就AK了,可惜啊,还有就是D题手推和B题手推花了大部分时间,什么时候要好好去看看数学了。。。(这一次的比赛还是比较水的嘛QWQ)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
提供的源码资源涵盖了python应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值