P9859 [CCC 2008 S2] Pennies in the Ring 题解
怎么没找到
根据初中数学可以得出,原问题等于求:
这题我想了 1h 的线性做法,然后发现好像没有。
这题我们显然可以打一个
#include<bits/stdc++.h>
using namespace std;
int n,sum,a[25001];
int main(){
while(cin>>n&&n){
if(!a[n]){
sum=0;
for(int i=1;i<=n;i++){
for(int j=1;i*i+j*j<=n*n;j++) sum++;
}
a[n]=4*sum+4*n+1;
cout<<4*sum+4*n+1<<endl;
}
else cout<<a[n]<<endl;
}
}
这样显然是不行的,
哎?怎么过了?肯定是因为数据水,我们接着考虑怎么优化:
容易发现每次的内层循环中,
时间复杂度
#include<bits/stdc++.h>
using namespace std;
int n,sum,a[25001],b[25001];
int main(){
for(int i=1;i<=25000;i++) b[i]=i*i;
while(cin>>n&&n){
if(!a[n]){
sum=0;
for(int i=1;i<=n;i++){
int l=0,r=25000;
while(l<r){
int mid=l+r+1>>1;
if(b[mid]<=n*n-i*i) l=mid;
else r=mid-1;
}
sum+=l;
}
a[n]=4*sum+4*n+1;
cout<<4*sum+4*n+1<<endl;
}
else cout<<a[n]<<endl;
}
}
然而这种做法似乎也过不去,因为还是那样,如果
哎?怎么又过了?肯定是因为数据水,我们接着考虑怎么优化:
这时候肯定就有人说了:你前面说没有线性做法,现在又说单
确实没有,但是我们充分发扬人类智慧,直观感受一下:
我们感觉到:在矩形中,包含在圆里的点的数量一定比不包含在圆里的点的数量多很多,也就是说,设
我们考虑枚举每一个不在圆里的点,也就是找出那个很小的数字,这个跟那个暴力差不多,时间复杂度
#include<bits/stdc++.h>
using namespace std;
int n,sum,a[25001];
int main(){
while(cin>>n&&n){
if(!a[n]){
sum=0;
for(int i=1,j=n;i<=n;i++){
j=n;
while(i*i+j*j>n*n) sum++,j--;
}
a[n]=(n*2+1)*(n*2+1)-4*sum;
cout<<(n*2+1)*(n*2+1)-4*sum<<endl;
}
else cout<<a[n]<<endl;
}
}
附极限数据一组,供大佬们调试用。