青岛市程序设计竞赛冲刺②
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; }