• 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}logsqrt[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 }
     
     
  • 相关阅读:
    oracle 中增加、修改、删除字段
    Oracle 中int , number的区别
    [转]信息系统项目管理师考试论文写作技巧
    项目论证
    java中异步计算之Future
    vmstat例子
    页面重构工作者的必备素质,转载
    办公室人员对号入座太经典啦!
    大家多注意身体!
    经典!牛人汽车防盗秘笈
  • 原文地址:https://www.cnblogs.com/ost-xg/p/5722268.html
Copyright © 2020-2023  润新知