牛客挑战赛53

比赛链接

牛客挑战赛53

A.智乃哥哥的小迷题A

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

你当前站在数轴的原点 \({0}\) 处,你要移动到数轴上的一个正整数点 \({x}\) 处。
假如你当前的位置是 \({y}\) ,正在进行第 \({k}\) 次操作,你可以做出以下两种移动:

  • 移动到位置 \({ y + k}\)
  • 移动到位置 \({ y - 1}\)

你可以移动到数轴的负半轴上,试求移动到点 \({x}\) 的最小步数。

输入描述:

第一行,一个整数 \(T( 1 \le T \le 10^5 )\),表示有 \({T}\) 组数据。

接下来 \({T}\) 行,每行一个正整数表示 \(x(1\le x \le 10^{15} )\)

输出描述:

共输出\({T}\)组答案,对于每组
输出一行一个整数 \({ans}\) 表示答案。

输入

5
1
2
3
4
5

输出

1
3
2
3
4

解题思路

模拟

image

  • 时间复杂度:\(O(1)\)

代码

#include<bits/stdc++.h>
using namespace std;
using LL=long long;
LL s;
int t;
int main()
{
    for(scanf("%d",&t);t;t--)
    {
        scanf("%lld",&s);
        LL n=(-1+sqrt(1+8*s))/2;
        LL tmp;
        if(n&1)tmp=(n+1)/2*n;
        else
            tmp=n/2*(n+1);
        if(tmp==s)
            printf("%lld\n",n);
        else
        {
            if(n&1)tmp=(n+1)/2*n;
            else
                tmp=n/2*(n+1);
            while(tmp-s<2)
            {
                n++;
                if(n&1)tmp=(n+1)/2*n;
                else
                    tmp=n/2*(n+1);
            }
            printf("%lld\n",n);
        }
    }
    return 0;
}

B.简单的序列

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
Special Judge, 64bit IO Format: %lld

题目描述

你需要找到一个序列 \(A_1, A_2 … A_i … A_m\) 并且每个 \(A_i\) 都为质数或者 \({1}\) 或者 \({0}\) 使得\(\sum_{i = 1}^{m}{A_i} = s\)
对于每个询问,你需要找到最小的 \({m}\)

数据保证题目有解。

特别的是,如果 \({s=0}\) 那么你也至少需要一个 \({0}\) 来填满它。

输入描述:

第一行,一个整数 \(T( 1 \le T \le 1000 )\) ,表示有 \({T}\) 组数据。

接下来 \({T}\) 行,每行一个数 \(s( 0 \le s \le 10^7 )\) 如题目所述。

输出描述:

一共输出 \({T}\) 组。

假如你找到的答案是 : \({m}\) 以及序列 \({A}\)

输出的格式如下:

\({m}\)
\(A_1 + A_2 + … + A_i + … A_m = s\)

示例1

输入

1
11

输出

1
11 = 11

示例2

输入

1
545

输出

3
1 + 3 + 541 = 545

示例3

输入

1
0

输出

1
0 = 0

解题思路

哥德巴赫猜想:任一大于2的偶数,都可表示成两个素数之和。

对于大于2的偶数,可直接运用哥德巴赫猜想,拆开成两个质数相加的形式,而对于奇数,可分为 \(1+偶数\)\(2+质数\) 两种情况~

  • 时间复杂度:\(O(n)\)

代码

#include<bits/stdc++.h>
using namespace std;
int prime[1000000];
int m;
int v[10000005];
unordered_map<int,bool> mp;
void primes(int n)
{
    for(int i=2;i<=n;i++)
    {
        if(!v[i])
        {
            v[i]=i;
            prime[++m]=i;
        }
        for(int j=1;j<=m;j++)
        {
            if(v[i]<prime[j]||1ll*prime[j]*i>n)break;
            v[i*prime[j]]=prime[j];
        }
    }
}
int t,s;
int main()
{
    primes(10000005);
    for(int i=1;i<=m;i++)
        mp[prime[i]]=true;
    for(scanf("%d",&t);t;t--)
    {
        scanf("%d",&s);
        if(mp[s]||s==0||s==1)
        {
            puts("1");
            printf("%d = %d\n",s,s);
        }
        else if(s&1)
        {
            if(mp[s-2])
            {
                puts("2");
                printf("2 + %d = %d\n",s-2,s);
                continue;
            }
            puts("3");
            printf("1 + ");
            s--;
            for(int i=1;prime[i]<=s;i++)
                if(mp[s-prime[i]])
                {
                    printf("%d + %d = %d\n",prime[i],s-prime[i],s+1);
                    break;
                }
        }
        else
        {
            puts("2");
            for(int i=1;prime[i]<=s;i++)
                if(mp[s-prime[i]])
                {
                    printf("%d + %d = %d\n",prime[i],s-prime[i],s);
                    break;
                }
        }
    }
    return 0;
}
posted @ 2021-10-15 23:47  zyy2001  阅读(107)  评论(0编辑  收藏  举报