标签:
题意:
给定一个数x,求正整数y≥2y\geq 2y≥2,使得满足以下条件:
1.y-x的绝对值最小
2.y的质因数分解式中每个质因数均恰好出现2次。
思路:
开根号上下搜索,枚举素数的方,判断是否成立,题目数据1e18,开根1e9,故判断是否包含素数方只需要枚举4*1e4内的素数就够了,完全在可解范围之内;
#include <iostream> #include <stdio.h> #include <algorithm> #include <math.h> #include <cstdio> #include <cstring> #include <string> #include <string.h> #include <vector> #include <queue> #include <map> #include <set> using namespace std; #define ll long long const long long inf=(ll)1e15+88; const int maxn=(int)1e4+88; const int mod=1000000007; ll a[maxn]; bool ab(ll mid) { for(int i=2;i<maxn;i++) { if(a[i]==0&&mid%(i*i)==0) return false; } return true; } ll myabs(ll a) { if(a>0)return a; return -a; } int main() { // freopen("1010.in", "r", stdin); // freopen("out.txt", "w", stdout); for(int i=0;i<maxn;i++) a[i]=0; for(int i=2;i<maxn;i++) { if(a[i]!=0)continue; for(int q=2;i*q<maxn;i++) { a[i*q]=1; } } int t; cin>>t; while(t--) { ll n; cin>>n; if(n<=4)cout<<4-n<<endl;//因为最小素数方为4,小于4向前搜索没意义,故特判 else { ll m=(ll)sqrt(n); ll l=m,r=m; for(l;l>=2;l--)//开根向下去整 { if(ab(l)) break; } for(++r;r;r++)//因为开根强转相当于开根向下取整,在其下,r需在其上,++r正好包含 { if(ab(r)) break; } cout<<min(myabs(n-l*l),myabs(r*r-n))<<endl; } } return 0; }
注意:n之内的合数总可以通过根号n的区间来求解!!!时间复杂度即可降!!!
标签:
原文地址:http://www.cnblogs.com/aishuijdemiaomiao/p/5725231.html