zoukankan      html  css  js  c++  java
  • Codeforces Round #451 (Div. 2) E

    E. Squares and not squares
     

    Ann and Borya have n piles with candies and n is even number. There are ai candies in pile with number i.

    Ann likes numbers which are square of some integer and Borya doesn't like numbers which are square of any integer. During one move guys can select some pile with candies and add one candy to it (this candy is new and doesn't belong to any other pile) or remove one candy (if there is at least one candy in this pile).

    Find out minimal number of moves that is required to make exactly n / 2 piles contain number of candies that is a square of some integer and exactly n / 2 piles contain number of candies that is not a square of any integer.

    Input

    First line contains one even integer n (2 ≤ n ≤ 200 000) — number of piles with candies.

    Second line contains sequence of integers a1, a2, ..., an (0 ≤ ai ≤ 109) — amounts of candies in each pile.

    Output

    Output minimal number of steps required to make exactly n / 2 piles contain number of candies that is a square of some integer and exactly n / 2 piles contain number of candies that is not a square of any integer. If condition is already satisfied output 0.

    Examples
    input
    4
    12 14 30 4
    output
    2
    input
    6
    0 0 0 0 0 0
    output
    6
    input
    6
    120 110 23 34 25 45
    output
    3
    input
    10
    121 56 78 81 45 100 1 0 54 78
    output
    0
    Note

    In first example you can satisfy condition in two moves. During each move you should add one candy to second pile. After it size of second pile becomes 16. After that Borya and Ann will have two piles with number of candies which is a square of integer (second and fourth pile) and two piles with number of candies which is not a square of any integer (first and third pile).

    In second example you should add two candies to any three piles.

     题意:有n(偶数)个数字,分成两堆,一段全是x^2的数字,另一堆就不是,可以当不能正好分成两堆时,可以这样操作,让某个数加一或者减一。

    贪心问题,先把是x^2和不是X^2的数字记下来,cn1和cnt2分别来计数,当cnt1>cnt2时  就让(cnt1-cnt2)/2个x^2变成不是x^2,0就要操作两次,其它都是操作一次

    当cnt1 < cnt2时,让(cnt2-cnt1)/2个不是x^2的数字变成x^2的数字,方法是让cnt2个数字全变成x^2,用数组保存下来要操作的次数,按小到大排序,前(cnt2-cnt1)/2个数字相加就是答案了。

     1 import math
     2 n = int(input())
     3 a = list(map(int, input().split()))
     4 a.sort()
     5 st = []
     6 cnt1 = cnt2 = cnt3 = 0
     7 for x in a:
     8     tmp = int(math.sqrt(x))
     9     if x == 0:
    10         cnt3 += 1
    11     if tmp*tmp == x:
    12         cnt1 += 1
    13     else :
    14         st.append(x)
    15         cnt2 += 1
    16 ans = 0
    17 if cnt1 > cnt2:
    18     cnt1 -= cnt3
    19     if cnt1 >= (n/2-cnt2):
    20         print(int(n/2-cnt2))
    21     else:
    22         print(int(cnt1+2*(n/2-cnt2-cnt1)))
    23 elif cnt1 < cnt2:
    24     vs = []
    25     for x in st:
    26         tmp = int(math.sqrt(x))
    27         MIN = min(x-tmp*tmp,(tmp+1)*(tmp+1)-x)
    28         vs.append(MIN)
    29     vs.sort()
    30     for i in range(int((cnt2-cnt1)/2)):
    31         ans += vs[i]
    32     print(ans)
    33 else :
    34     print('0')
     1 #include <bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 vector<ll> vs, st;
     5 int main() {
     6     /*
     7     #ifndef ONLINE_JUDGE   
     8     freopen("in.txt", "r", stdin);  
     9     #endif // ONLINE_JUDGE  
    10     */
    11     ll n, x;
    12     cin >> n;
    13     ll cnt1 = 0,cnt2 = 0, cnt3 = 0;
    14     for(int i = 0; i < n; i ++) {
    15         cin >> x;
    16         ll tmp = sqrt(x);
    17         if(x == 0) cnt3 ++;
    18         if(tmp * tmp == x) {
    19             cnt1++;
    20         } else {
    21             st.push_back(x);
    22             cnt2++;
    23         }
    24     }
    25     ll ans = 0;
    26     if(cnt1 > cnt2) {
    27         cnt1 -= cnt3;
    28         if(cnt1 >= (n/2-cnt2)) printf("%lld
    ",(n/2-cnt2));
    29         else printf("%d
    ",cnt1 + 2*(n/2-cnt2-cnt1));
    30     } else if(cnt1 < cnt2) {
    31         int len = st.size();
    32         for(int it = 0; it != len; it++) {
    33             ll tmp = sqrt(st[it]);
    34             ll MIN = min(st[it]-tmp*tmp,(tmp+1)*(tmp+1)-st[it]);
    35             vs.push_back(MIN);
    36         }
    37         sort(vs.begin(), vs.end());
    38         for(int i = 0; i < (cnt2-cnt1)/2; i ++) {
    39             ans += vs[i];
    40         }
    41         printf("%lld
    ",ans);
    42     } else printf("0
    ");
    43     return 0;
    44 }
  • 相关阅读:
    关于Django 报错 ImportError: cannot import name RegexUrlResolver解决
    Git版本控制
    java Labmda表达式
    java注解&反射
    maven
    数据库
    为什么java中子类重写父类的方法时声明抛出异常不能比父类范围大
    【Linux】Linux基本命令
    阿里云服务器linux环境搭建SSM项目(一)--Linux环境配置jdk和Tomcat.md
    阿里云服务器linux环境搭建SSM项目(二)--linux环境配置mysql5.7.md
  • 原文地址:https://www.cnblogs.com/xingkongyihao/p/8167744.html
Copyright © 2011-2022 走看看