HDU 5778 abs (暴力枚举)

abs

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)

Problem Description
Given a number x, ask positive integer y2, that satisfy the following conditions:
1. The absolute value of y - x is minimal
2. To prime factors decomposition of Y, every element factor appears two times exactly.
 

 

Input
The first line of input is an integer T ( 1T50)
For each test case,the single line contains, an integer x ( 1x1018)
 

 

Output
For each testcase print the absolute value of y - x
 

 

Sample Input
5
1112 4290 8716 9957 9095
 

 

Sample Output
23 65 67 244 70
 
描述:
  给你一个long long范围的数x,然后让你找到一个数y,数y的质因数分解中,每个数刚好出现两次,输出的是abs(x-y)最小。
 
题解:
  比赛的时候没想出来,后来看题解发现竟然这么水= =。
  官方题解:由于y质因数分解式中每个质因数均出现2次,那么y是一个完全平方数,设y=z*z,题目可转换成求z,使得每个质因数出现1次. 我们可以暴力枚举z,检查z是否符合要求,显然当z是质数是符合
  要求,由素数定理可以得,z的枚举量在logn级别 复杂度 O(\sqrt[4]{n}log\sqrt[2]{n}4​​n​​log2​​n​​);
  就只需要在x周围枚举就好了,枚举的范围题解说很小。。。然后z判断是不是满足条件的也很简单。
 
代码:
 1 #include<cstdio>
 2 #include<cmath>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<vector>
 6 #include<stack>
 7 #include<cstring>
 8 #include<queue>
 9 #include<set>
10 #include<string>
11 #include<map>
12 #define inf 9223372036854775807
13 #define INF 9e7+5
14 #define PI acos(-1)
15 using namespace std;
16 typedef long long ll;
17 typedef double db;
18 const int maxn = 1e5 + 5;
19 const int mod = 1e9 + 7;
20 const db eps = 1e-9;
21 
22 // 判断这个数满不满足条件。
23 bool ok(ll x) {
24     for (ll i = 2; i*i <= x; i++) {
25         int num = 0;
26         while (x % i == 0) { /*这里的i满足while的条件肯定是素数,为什么呢,就和素数筛选法的原理差不多。*/
27             num++;
28             x /= i;
29             if (num > 1) return false;// 如果大约两次就不满足条件
30         }
31     }
32     return true;
33 }
34 
35 ll abss(ll x) {
36     return x >= 0 ? x : -x;
37 }
38 
39 void solve() {
40     ll n, ans; cin >> n;
41     ll z = sqrt(n+0.5D);
42     //cout << z << endl;
43     for (ll i = 0; ; i++) {
44         ll tmp = z + i;
45         if (tmp * tmp >= n && ok(tmp)) { /*因为不比比n小,所以要满足 >= n这个条件,测试样例的时候发现8开方是2,然后2是满足条件的,此时找到的答案就不对。*/
46             ans = abss(tmp*tmp - n);
47             //cout << tmp << endl;
48             break;
49         }
50     }
51     for (ll i = 0; ;i++) {
52         ll tmp = z - i;
53         if (ok(tmp)) {
54             ans = min(ans, abs(tmp*tmp - n));
55             break;
56         }
57     }
58     if (n < 4) ans = 4 - n; /*小于4的开方都是1,然后用ok函数判断的1是满足条件的,但是1不是素数,所以要特判。*/
59     cout << ans << endl;
60 }
61 
62 int main()
63 {
64     //cin.sync_with_stdio(false);
65     //freopen("isharp.in", "r", stdin);
66     //freopen("hh.txt", "w", stdout);
67     int t; cin >> t;
68 
69     while (t--)
70         solve();
71     return 0;
72 }

 

 
 
posted @ 2016-07-31 02:18  ost_xg  阅读(743)  评论(0编辑  收藏  举报