Help cupid
Mean:
地球被划分为24个时区(-11~23),现在给出n个人的时区,将这n个人两两配对,使得n/2对配偶的时区差值之和最小。
analyse:
由于给的都是整数,而且只有24个时区,首先统计每个时区有多少人。
然后每个时区的人数都%2,因为同一时区的两个人差值为0。
接着就是枚举人数不为零的时区的人数。
根据贪心的思想,我们知道除了第一个和最后一个外,其他人都是和相邻两个的其中一个匹配,为什么呢?自己画个圈去证明。
对于第一个和最后一个,要么最后特判一下,要么直接在数组后面接一个每个元素+24的数组(处理环常用方法),暴力一下就行。
Time complexity: O(N)
Source code:
/*
* this code is made by crazyacking
* Verdict: Accepted
* Submission Date: 2015-07-26-08.27
* Time: 0MS
* Memory: 137KB
*/
#include <queue>
#include <cstdio>
#include <set>
#include <string>
#include <stack>
#include <cmath>
#include <climits>
#include <map>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#define LL __int64
#define ULL unsigned long long
using
namespace
std;
int
a
[
50
],
ti
[
50
];
int
main()
{
ios_base
::
sync_with_stdio(
false);
cin
.
tie(
0);
int n
,
tmp;
while(
cin
>>n)
{
memset(
a
,
0
,
sizeof
a);
for(
int
i
=
0;
i
<n;
++
i)
{
cin
>>
tmp;
a
[
tmp
+
11
]
++;
}
for(
int
i
=
0;
i
<
50;
++
i)
a
[
i
]
&=
1;
int
cnt
=
0;
for(
int
i
=
0;
i
<
50;
++
i)
{
if(
a
[
i
])
ti
[
cnt
++
]
=
i;
}
int
c
=
cnt;
for(
int
i
=
0;
i
<
c;
++
i)
ti
[
cnt
++
]
=
ti
[
i
]
+
24;
LL
ans
=
LLONG_MAX;
for(
int
i
=
0;
i
<
c;
++
i)
{
LL
sum
=
0;
for(
int
j
=
0;
j
<
c;
j
+=
2)
sum
+=
ti
[
i
+
j
+
1
]
-
ti
[
i
+
j
];
ans
=
ans
<
sum
?
ans:
sum;
}
if(
ans
==
LLONG_MAX)
cout
<<
0
<<
endl;
else
cout
<<
ans
<<
endl;
}
return
0;
}
/*
*/