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

412 14 30 4

output

2

input

60 0 0 0 0 0

output

6

input

6120 110 23 34 25 45

output

3

input

10121 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",(n/2-cnt2));
29         else printf("%d\n",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\n",ans);
42     } else printf("0\n");
43     return 0;
44 }

原文地址:https://www.cnblogs.com/xingkongyihao/p/8167744.html

时间: 2024-08-30 13:56:37

Codeforces Round #451 (Div. 2) E的相关文章

Codeforces Round #451 (Div. 2) ABC

A. Rounding Vasya has a non-negative integer n. He wants to round it to nearest integer, which ends up with 0. If n already ends up with 0, Vasya considers it already rounded. For example, if n = 4722 answer is 4720. If n = 5 Vasya can round it to 0 

【Codeforces Round #451 (Div. 2) D】Alarm Clock

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 尺取法+二分. 类似滑动窗口. 即左端点为l,右端点为r. 维护a[r]-a[l]+1总是小于等于m的就好. (大于m就右移左端点) 然后看看里面的数字个数是不是小于k; 不是的话让l..r中最右边那个数字删掉就好. ->链表优化一下即可. [代码] /* 1.Shoud it use long long ? 2.Have you ever test several sample(at least therr) yourself

Codeforces Round #451 (Div. 2) F Restoring the Expression

题意: 有一个a+b=c的等式,去掉两个符号,把三个数连在一起得到一个数 给出这个数,要求还原等式,length <= 1e6 三个数不能含有前导0,保证有解 解法: 铁头过题法,分类然后各种判断 我分了5种情况 0.开头字符为0, 那么结果一定是0+a=a的形式 然后4种情况 1.len(a) >= len(b) 且 len(c) == len(a) 2.len(a) <= len(b) 且 len(c) == len(b) 3.len(a) >= len(b) 且 len(c)

Codeforces Round #451 Div. 2 C D E

C.Phone Numbers 之前没有做过字典树--感觉这个题字典树也能做--就拿来练一练字典树--板子好多地方写的都不够好,还需要继续改-- emmm这个--卡了好久啊--不过好在还是debug出来了--orz 虽然是处理后缀的问题,但是只需要reverse一下就可以变成前缀问题了2333333,然后每一次的字符串都插进去,最后从叶子到根遍历输出就可以了-- 不过我好像--连叶子到根的遍历都写不好呜呜呜--ps:这里只是为了用trie而用trie--其实用map维护一下直接暴力求解就可以--

Codeforces Round #451 (Div. 2)【A,B,C,D,E】【C题:模拟 D题:尺取+贪心 E题:思维+优先队列维护最值】

特判最后一位即可 1 #include<bits/stdc++.h> 2 3 using namespace std; 4 #define int long long 5 6 signed main(){ 7 int n;cin>>n;int t=n%10; 8 if(t==0) cout<<n; 9 else if(t>5) { 10 cout<<(n+10-t); 11 } 12 else { 13 cout<<(n-t); 14 }

Codeforces Round #258 (Div. 2) B. Sort the Array(简单题)

题目链接:http://codeforces.com/contest/451/problem/B ---------------------------------------------------------------------------------------------------------------------------------------------------------- 欢迎光临天资小屋:http://user.qzone.qq.com/593830943/ma

Codeforces Round #258 (Div. 2) A. Game With Sticks(数学题)

题目链接:http://codeforces.com/contest/451/problem/A ---------------------------------------------------------------------------------------------------------------------------------------------------------- 欢迎光临天资小屋:http://user.qzone.qq.com/593830943/ma

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i

Codeforces Round #424 (Div. 2) D. Office Keys(dp)

题目链接:Codeforces Round #424 (Div. 2) D. Office Keys 题意: 在一条轴上有n个人,和m个钥匙,门在s位置. 现在每个人走单位距离需要单位时间. 每个钥匙只能被一个人拿. 求全部的人拿到钥匙并且走到门的最短时间. 题解: 显然没有交叉的情况,因为如果交叉的话可能不是最优解. 然后考虑dp[i][j]表示第i个人拿了第j把钥匙,然后 dp[i][j]=max(val(i,j),min(dp[i-1][i-1~j]))   val(i,j)表示第i个人拿