牛客挑战赛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
解题思路
模拟
- 时间复杂度:\(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;
}