题目描述:
多次查询[l,r]范围内的完全平方数个数
定义整数x为完全平方数当且仅当可以找到整数y使得y*y=x
输入:
先输入一个整数N,接下来N行,每行输入一个范围;
输出:
一个整数,范围中的完全平方数的个数;
思路:
我们需要的是l,r之间能够开方并且开方结果为整数的数,那么我们就可以反其道而行之,把l,r分别开方,求之间的整数的个数即可;虽然:我们可以使用stl中的upper_bound以及lower_bound直接进行运算,但是为了锻炼自己的代码能力所以还是自己手打一下这两个函数吧;
因为按照题目来的,所以我写的lower与upper与stl中的有所差异。
lower:
int lower(int l,int r,int number){ int mid=(l+r)>>1; while(l<=r){ mid =(l+r)>>1;//mid要随l,r的变化而更新; if(mid>=number) r=mid-1;//因为找的是最左边的该数值,所以即使等于也要左移,直到最左边为止。 else { l=mid+1; } } return l; }
upper
类似于lower就不做过多解释了;
int upper(int l,int r,int number){ // cout<<number<<endl; int mid =(l+r)>>1; while(l<=r){ mid =(l+r)>>1; if(mid>number)r=mid-1; else{ l=mid+1; } } return l; }
最后就是AC代码了
#include<iostream> #include<cmath> using namespace std; const int type=36125; int lower(int l,int r,int number){ int mid=(l+r)>>1; while(l<=r){ mid =(l+r)>>1; if(mid>=number) r=mid-1; else { l=mid+1; } } return l; } int upper(int l,int r,int number){ int mid =(l+r)>>1; while(l<=r){ mid =(l+r)>>1; if(mid>number)r=mid-1; else{ l=mid+1; } } return l; } int main(){ int n; cin>>n; while(n--){ int x,y; cin>>x>>y; int L,R; if(x-(int)sqrt(x)*(int)sqrt(x)>0){ L=upper(0,type,sqrt(x)); }else{ L=lower(0,type,sqrt(x)); } R=upper(0,type,sqrt(y)); int ans = max (R-L,0); cout<<ans<<endl; } return 0; }
笱蒻一枚,有错请指教