青岛市程序设计竞赛冲刺②
2022青岛市小学组第三题
原题:






代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,ans=0,t;
int main(){
freopen("turn.in","r",stdin);
freopen("turn.out","w",stdout);
cin>>n;t=sqrt(n);
if(n==2)cout<<0;
else if(t*t!=n)cout<<-1;
else{
ans=n-2+1;
while(t!=2){
ll tmp=(t-1)*(t-1);
ans+=tmp-t+1;
t--;
}
cout<<ans;
}
return 0;
}
解题思路:
分三种情况,第一种,n=2,直接输出0
第二种,sqrt(n)2≠n,直接输出-1
第三种,sqrt(n)2=n,这个数会每次先遍历到n,从n开方,遍历到(sqrt(n)-1)2 ,从(sqrt(n)-1)2开方,重复执行这种操作,直至开方结果等于2,累计次数即为答案
也可以用平方和的通项公式,n(n+1)(2n+1)/6
#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
long long n,p;
int main(){
scanf("%lld",&n);
if(n==2){
printf("0\n");
return 0;
}
long long t=sqrt(n);
if(t*t!=n)printf("-1\n");
else{
long long ans=n-2+t-1;
p = t - 1;
ans = ans + (p * (p + 1) * (2 * p + 1) / 6 - 1)-(p*(p+1)/2-1)-(t-2);
printf("%lld\n",ans);
}
return 0;
}
也可以提前算出平方数,求和
#include<bits/stdc++.h>
#define MX 1000000
typedef long long int LL;
using namespace std;
LL n,a[MX + 10] = {0,0};
LL i,ans,x,p,k = 1;
int main()
{
for(i = 2; i * i <= 1e12; i++)
{
a[++k] = i * i;
}
scanf("%lld",&n);
p = sqrt(n);
if(n == 2)
{
ans = 0;
}
else if(p * p != n)
{
ans = -1;
}
else
{
x = lower_bound(a + 1,a + k + 1,n) - a;
p = 2;
do
{
ans = ans + (a[x] - p) + 1;
p = x;
x--;
}
while(x >= 2);
}
cout << ans << endl;
return 0;
}

浙公网安备 33010602011771号